NDK Samples [3] - hello-libs
NDK Samples目錄: ofollow,noindex">GoogleSamples - NDK Samples
專案地址: https://github.com/googlesamples/android-ndk/tree/master/hello-libs
說明文件: https://github.com/googlesamples/android-ndk/tree/master/hello-libs/README.md
該專案演示如何在Android+Studio/">Android Studio上使用第三方的C / C++庫。
最低要求:
- Android Studio 版本大於 3.0
該專案演示如何在Android Studio上使用第三方的C / C++庫:
- CmakeList.txt
主要關注的檔案,第三方庫的匯入使用,主要是通過CmakeList中的配置實現的。 - MainActivity / hello-libs.cpp
MainActivity 負責呼叫 hello-libs.cpp 唯一的方法 stringFromJNI,無需分析。 - build.gradle(app)
匯入第三方動態庫,需要把動態庫新增到工程中一起打包,需要在gradle中配置。
匯入專案,切換到Project目錄顯示,可以看到第三方的庫的路徑如下:

其中gmath目錄下的為靜態庫.a檔案,gperf目錄下的動態庫.so檔案。
為了使用引入的第三方動態庫,需要在Gradle中配置動態庫的路徑:
sourceSets { main { jniLibs.srcDirs = ['../distribution/gperf/lib'] } }
CmakeList.txt檔案,引用第三方靜態 / 動態庫 是通過CmakeList的配置實現的:
# 設定 Cmake 最低版本要求為 3.4.1 cmake_minimum_required(VERSION 3.4.1) # 設定 distribution_DIR 變數,值為 distribution目錄 # !CMAKE_SOURCE_DIR 指的是Cmake工程頂層目錄 # !此處 in source 情況下,即為 CmakeList.txt 所在的目錄 # !https://cmake.org/cmake/help/latest/variable/CMAKE_SOURCE_DIR.html set(distribution_DIR ${CMAKE_SOURCE_DIR}/../../../../distribution) # = = = = = = 匯入靜態庫 libgmath.a = = = = = = # 以只讀方式,向工程新增一個靜態庫 lib_gmath # 一些帖子上說的歸檔檔案,其實就是靜態庫檔案 # !IMPORTED:https://cmake.org/cmake/help/v3.0/prop_tgt/IMPORTED.html?highlight=imported # !add_library:https://cmake.org/cmake/help/latest/command/add_library.html#imported-libraries add_library(lib_gmath STATIC IMPORTED) # 設定靜態庫 lib_gmath 的主檔案路徑 # !set_target_properties:https://cmake.org/cmake/help/latest/command/set_target_properties.html # !IMPORTED_LOCATION:https://cmake.org/cmake/help/v3.0/prop_tgt/IMPORTED_LOCATION.html set_target_properties(lib_gmath PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/gmath/lib/${ANDROID_ABI}/libgmath.a) # = = = = = = = = = = = = = = = = = = = = = = # = = = = = = 匯入動態庫 libgperf.so = = = = = = # 以只讀方式,向工程新增一個動態庫 lib_gperf add_library(lib_gperf SHARED IMPORTED) # 設定動態庫 lib_gperf 的主檔案路徑 set_target_properties(lib_gperf PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/gperf/lib/${ANDROID_ABI}/libgperf.so) # = = = = = = = = = = = = = = = = = = = = = = # 新增C++編譯器的編譯選項,支援C++11標準和GNU擴充套件特性 # !CXXFLAGS:https://cmake.org/cmake/help/latest/envvar/CXXFLAGS.html set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") # 新增動態庫 hello-libs,並列出相關的原始檔 # 這裡相當於根據列出的原始檔生成 hello-libs 動態庫 # 預設情況下,庫檔案將在與呼叫命令的源目錄對應的構建樹目錄中建立 # !add_library:https://cmake.org/cmake/help/latest/command/add_library.html#normal-libraries add_library(hello-libs SHARED hello-libs.cpp) # 指定動態庫 hello-libs 編譯所依賴的標頭檔案的目錄 # !target_include_directories:https://cmake.org/cmake/help/v3.0/command/target_include_directories.html target_include_directories(hello-libs PRIVATE ${distribution_DIR}/gmath/include ${distribution_DIR}/gperf/include) # 指定動態庫 hello-libs 編譯所依賴的庫檔案 # !target_link_libraries:https://cmake.org/cmake/help/v3.3/command/target_link_libraries.html target_link_libraries(hello-libs android lib_gmath lib_gperf log)
stringFromJNI方法:
extern "C" JNIEXPORT jstring JNICALL Java_com_example_hellolibs_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) { // 原始碼的註釋說明:為了方便,這個方法就不在子執行緒跑了。。 // GetTicks是動態庫gperf的方法,根據邏輯推斷是獲取一個當前時間相關的標識 auto ticks = GetTicks(); // 迴圈模擬耗時操作 for (auto exp = 0; exp < 32; ++exp) { // gpower是靜態庫gmath的方法 volatile unsigned val = gpower(exp); (void) val;// to silence compiler warning } // 推斷是計算耗時操作的耗時 ticks = GetTicks() - ticks; // 列印耗時資訊 LOGI("calculation time: %" PRIu64, ticks); // 介面上只能看到一串"Hello from JNI LIBS!" return env->NewStringUTF("Hello from JNI LIBS!"); }
經過分析得知,該專案主要演示:
通過CmakeList在Android Studio上使用第三方的C / C++庫。