您现在的位置是:首页 > 文章详情

Android JNI开发系列(二)HelloWorld

日期:2018-10-11点击:365

入门HelloWorld

新建项目

  • Configure your new project部分选中 Include C++ Support 复选框

  • Next

  • 正常填写所有其他字段并完成向导接下来几个部分

  • 在向导的Customize C++ Support 部分,您可以使用谢列选项自定义项目:

    • C++ Standard : 使用下拉列表选择使用的C++标准。选择Toolchain Defalut 会使用默认的CMake设置。

    • Exception Support : 如果您希望启用对C++异常处理的支持,请选中该复选框,Android Studio 会将 -fexception标志添加到模块级别build.gradle 文件的cppFlag中,Gradle会将其传递到CMake.

    • Runtime Type Information Support: 如果您希望支持RTTI,请选中该复选框,如果启用Android Studio会将**-frtti标志添加到模块级别build.gradle** 文件的cppFlag中,Gradle会将其传递到CMake.

  • finish

项目结构

  • cpp 组

    您可以找到属于项目的所有原生源文件、标头和预构建库。对于新项目,Android Studio 会创建一个示例 C++ 源文件 native-lib.cpp,并将其置于应用模块的 src/main/cpp/ 目录中。本示例代码提供了一个简单的 C++ 函数 stringFromJNI(),此函数可以返回字符串“Hello from C++”。要了解如何向项目添加其他源文件,请参阅介绍如何创建新的原生源文件的部分。

  • External Build File :

    您可以找到 CMake 或 ndk-build 的构建脚本。与 build.gradle 文件指示 Gradle 如何构建应用一样,CMake 和 ndk-build 需要一个构建脚本来了解如何构建您的原生库。对于新项目,Android Studio 会创建一个 CMake 构建脚本 CMakeLists.txt,并将其置于模块的根目录中。要详细了解此构建脚本的内容,请参阅介绍如何创建 Cmake 构建脚本的部分。

构建过程

Gradle 调用您的外部构建脚本 CMakeLists.txt。 CMake 按照构建脚本中的命令将 C++ 源文件例如 native-lib.cpp 编译到共享的对象库中,并命名为 libnative-lib.so,Gradle 随后会将其打包到APK 中。

创建 CMake 构建脚本

如果您的原生源文件还没有 CMake 构建脚本,则您需要自行创建一个并包含适当的 CMake 命令。CMake 构建脚本是一个纯文本文件,您必须将其命名为 CMakeLists.txt。本部分介绍了您应包含到构建脚本中的一些基本命令,用于在创建原生库时指示 CMake 应使用哪些源文件。

要创建一个可以用作 CMake 构建脚本的纯文本文件,请按以下步骤操作

  • 从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。
  • 右键点击 您的模块 的根目录并选择 New > File。
  • 输入“CMakeLists.txt”作为文件名并点击 OK。

要指示 CMake 从原生源代码创建一个原生库,请将 cmake_minimum_required()add_library() 命令添加到您的构建脚本中:

# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. //指定可用的CMake构建脚本版本 cmake_minimum_required(VERSION 3.4.1) # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. # Gradle automatically packages shared libraries with your APK. # 指定需传入三个参数(函数库名称,库类型,依赖源文件相对路径) add_library( # Sets the name of the library. native-lib # SHARED 动态链接库 STATIC 静态链接库 Sets the library as a shared library. SHARED # 相对路径 Provides a relative path to your source file(s). src/main/cpp/native-lib.cpp ) # Searches for a specified prebuilt library and stores the path as a # variable. Because CMake includes system libraries in the search path by # default, you only need to specify the name of the public NDK library # you want to add. CMake verifies that the library exists before # completing its build. # 用于定位NDK中的库 # 需要传入两个参数(path变量、ndk库名称) find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. # 指定CMake查询库的名称,即在ndk 开发包中查询liblog.so函数库,将其路径赋值给log-lib log ) # Specifies libraries CMake should link to your target library. You # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. # 指定关联到原生库的库 target_link_libraries( # Specifies the target library. # 指定目标库,与善变的函数名保持一致 native-lib # Links the target library to the log library # included in the NDK. # 链接的库,根据log-lib变量对应liblog.so函数库 ${log-lib} ) 

NOTE:

  • 使用 add_library() 向您的 CMake 构建脚本添加源文件或库时,Android Studio 还会在您同步项目后在 Project 视图下显示关联的标头文件。不过,为了确保 CMake 可以在编译时定位您的标头文件,您需要将 include_directories() 命令添加到 CMake 构建脚本中并指定标头的路径:
# Specifies a path to native header files. include_directories(src/main/cpp/include/) 
  • 将 find_library() 命令添加到您的 CMake 构建脚本中以定位 NDK 库,并将其路径存储为一个变量。您可以使用此变量在构建脚本的其他部分引用 NDK 库。以下示例可以定位 Android 特定的日志支持库并将其路径存储在 log-lib 中:
find_library( # Defines the name of the path variable that stores the # location of the NDK library. log-lib # Specifies the name of the NDK library that # CMake needs to locate. log ) 
  • 为了确保您的原生库可以在 log 库中调用函数,您需要使用 CMake 构建脚本中的 target_link_libraries() 命令关联库:
find_library(...) # Links your native library against one or more other native libraries. target_link_libraries( # Specifies the target library. native-lib # Links the log library to the target library. ${log-lib} ) 
  • NDK 还以源代码的形式包含一些库,您在构建和关联到您的原生库时需要使用这些代码。您可以使用 CMake 构建脚本中的 add_library() 命令,将源代码编译到原生库中。要提供本地 NDK 库的路径,您可以使用 ANDROID_NDK 路径变量,Android Studio 会自动为您定义此变量。

以下命令可以指示 CMake 构建 android_native_app_glue.c,后者会将 NativeActivity 生命周期事件和触摸输入置于静态库中并将静态库关联到 native-lib:

add_library( app-glue STATIC ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c ) # You need to link static libraries against your shared native library. target_link_libraries( native-lib app-glue ${log-lib} ) 
  • 添加预构建库与为 CMake 指定要构建的另一个原生库类似。不过,由于库已经预先构建,您需要使用 IMPORTED 标志告知 CMake 您只希望将库导入到项目中:
add_library( imported-lib SHARED IMPORTED ) 

然后,您需要使用 set_target_properties() 命令指定库的路径,如下所示。

某些库为特定的 CPU 架构(或应用二进制接口 (ABI))提供了单独的软件包,并将其组织到单独的目录中。此方法既有助于库充分利用特定的 CPU 架构,又能让您仅使用所需的库版本。要向 CMake 构建脚本中添加库的多个 ABI 版本,而不必为库的每个版本编写多个命令,您可以使用 ANDROID_ABI 路径变量。此变量使用 NDK 支持的一组默认 ABI,或者您手动配置 Gradle 而让其使用的一组经过筛选的 ABI。例如:

add_library(...) set_target_properties( # Specifies the target library. imported-lib # Specifies the parameter you want to define. PROPERTIES IMPORTED_LOCATION # Provides the path to the library you want to import. imported-lib/src/${ANDROID_ABI}/libimported-lib.so ) 
  • 为了确保 CMake 可以在编译时定位您的标头文件,您需要使用 include_directories() 命令,并包含标头文件的路径:
include_directories( imported-lib/include/ ) 
  • 要将预构建库关联到您自己的原生库,请将其添加到 CMake 构建脚本的 target_link_libraries() 命令中:
target_link_libraries( native-lib imported-lib app-glue ${log-lib} ) 

构建应用时,Gradle 会自动将导入的库打包到 APK 中。您可以使用 APK 分析器验证 Gradle 将哪些库打包到您的 APK 中。如需了解有关 CMake 命令的详细信息,请参阅 CMake 文档。

新建Demo时候遇到的坑

  • CMakeList.txt

    add_libary() 脚本,报错,如果写了新的Cpp/C文件,rebuld不会提示并生成,直接报错在该节点首行,

    应先在对应目录新建Cpp/C文件,再引入

  • 注意修改 target_link_libraries 下的 target Libary

原文链接:https://my.oschina.net/caipeng/blog/2243624
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章