NDK Samples目录: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上使用第三方的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++库。