NDK Samples [3] - hello-libs

96
七零八落问号
0.1 2018.11.11 23:59* 字数 337

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++库。


最低要求:

  1. Android Studio 版本大于 3.0

该项目演示如何在Android Studio上使用第三方的C / C++库:

  1. CmakeList.txt
    主要关注的文件,第三方库的导入使用,主要是通过CmakeList中的配置实现的。
  2. MainActivity / hello-libs.cpp
    MainActivity 负责调用 hello-libs.cpp 唯一的方法 stringFromJNI,无需分析。
  3. 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++库。

Google官方Demo
Web note ad 1