Android3.4 NDK编程总结

作者: clown无双 | 来源:发表于2019-08-29 12:33 被阅读0次

    最近项目需要,要做串口的通信,涉及到NDK的编程,在网上查了下资料,发现基本清一色的都是很旧的,抄自几年前同一位大神的模板文,晦涩难懂。CSDN的付费都没法看。其实这几年谷歌一直在做相关的优化,NDK同样也做了很多改进,今天我写一下,算是个总结,方便以后查阅,有兴趣的过来我们可以一起交流一下新的技术。

    一、关于旧资料的几点澄清

    1.新建project时,如果想包含NDK编程,已经没有所谓的复选框来选择“include C++”,从Android studio3.3开始,谷歌在模板选择时单独做了一个,直接选择就可以,如下图1.进去以后会有一个CPP的文件夹,里边有一儿c++文件,同时build.gradle也已经配置好了,在默认文件里进行编程修改增删就行,具体的就不再赘述。

    PS:Next以后,会让你选择C++ Standard,其中使用下拉列表选择您希望使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置。

    图1

    2.网上好多教程涉及到要在命令行进行头文件生成的,我在实际操作的时候并没有这一步,不敢说不对,但是这里我没做过多研究,只是声明一下不需要也行。

    3.关于cMake和ndk-build的说明,这是两种编译NDK库的方法,谷歌官方文档写的很是清楚,现在官方默认支持的是cMake,也就是说你现在如果在工程里新建本地库进行NDK编程,你应该用cMake;如果你之前的工程用的是ndk-build,那么Android studio也支持这种方法。至于两者具体的区别,不做赘述,就补充一下,cMake需要对应的脚本文件“CMakeLists.txt”,ndk-build需要两个.mk的文件(  Android.mk 、 Application.mk)。本文我们只讲述相关cMake的方法。

    二、基础知识废话

    Native Develope Kit(NDK):这套工具集允许您为 Android 使用 C 和 C++ 代码,并提供众多平台库,让您可以管理原生 Activity 和访问物理设备组件,例如传感器和触摸输入。

    cMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。

    LLDB:一种调试程序,Android Studio 使用它来调试native code。

    JNI:Java Native Interface,Java本地接口。

    你可以使用 SDK 管理器安装这些组件:

    在打开的项目中,从菜单栏选择 Tools > Android > SDK Manager

    点击 SDK Tools 标签。

    选中 LLDBCMake 和 NDK 旁的复选框,如图 2 所示。

    图2

    从 SDK 管理器中安装 LLDB、CMake 和 NDK。

    点击 Apply,然后在弹出式对话框中点击 OK

    安装完成后,点击 Finish,然后点击 OK

    三、关于添加NDK编程

    1.创建项目时即包含有NDK编程,如上所述已经讲过。新建完成后,视图如下图3。

    图3

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

    2.在已有代码中增加NDK编程,这是本文主要要讲述部分。

    四、向现有项目添加C/C++代码

    (一)主要步骤:

    1.创建新的原生源文件(指代C/C++代码)并将其添加到您的 Android Studio 项目中。

        如果您已经拥有原生代码或想要导入预构建的原生库,则可以跳过此步骤。

    2.创建 CMake 构建脚本,将您的原生源代码构建到库中。如果导入和关联预构建库或平台库,您       也需要此构建脚本。

       如果您的现有原生库已经拥有 CMakeLists.txt 构建脚本,则可以跳过此步骤。

    3.提供一个指向您的 CMake 脚本文件的路径,将 Gradle 关联到您的原生库。Gradle  使用构建脚       本将源代码导入您的 Android Studio 项目并将原生库(SO 文件)打包到 APK 中。

    (二)创建新的原生源文件

    要在应用模块的主源代码集中创建一个包含新建原生源文件的 cpp/ 目录,请按以下步骤操作:

    1.从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。

    2.导航到 你的模块> src,右键点击 main 目录,然后选择 New > Directory

    3.为目录输入一个名称(例如 cpp)并点击 OK

    4.右键点击您刚刚创建的目录,然后选择 New > C/C++ Source File

    5.为你的源文件输入一个名称,例如 native-lib。(我的是JNIcpp,只要前后对应就可以)

    6.从 Type 下拉菜单中,为您的源文件选择文件扩展名,例如 .cpp。

    如果你还希望创建一个标头文件,请选中 Create an associated header 复选框。

    点击 OK

    7.在你的.cpp文件中输入以下图片内容;

    示例图片

    8.新建JNIhelp类,内容如下:

    示例图片

    9.MainActivity中代码如下:

    示例图片

    (三)创建 CMake 构建脚本

    CMake 构建脚本是一个纯文本文件,你必须将其命名为 CMakeLists.txt。本部分介绍了你应包含到构建脚本中的一些基本命令,用于在创建原生库时指示 CMake 应使用哪些源文件。

    1.从 IDE 的左侧打开 Project 窗格并从下拉菜单中选择 Project 视图。

    2.右键点击 你的模块 的根目录并选择 New > File

    3.输入“CMakeLists.txt”作为文件名并点击 OK

    编辑内容如下两图图4和图5.(本来想上传高亮代码的,捣鼓了一会不会用简书传,只能截图了。大家可以先新建一个默认带NDK编程的工程,然后找到这TXT文件,把里边的内容复制过来就行,基本是一样的。)

    图4 图5

    上图有四个命令函数,基本看名字就能分辨作用,我就不一一写了,网上也能查到,不懂得私信问我也行。还有其他的命令,及添加多个库的方法,这里就不一一写了,大家可以去查。

    (四)将 Gradle 关联到原生库

    方法1、使用 Android Studio UI 

    1、从 IDE 左侧打开 Project 窗格并选择 Android 视图。

    2、右键点击您想要关联到原生库的模块(例如 app 模块),并从菜单中选择 Link C++ Project with Gradle。您应看到一个如图 4 所示的对话框。

    3、从下拉菜单中,选择 CMake 或 ndk-build

    如果你选择 CMake,请使用 Project Path 旁的字段为你的外部 CMake 项目指定 CMakeLists.txt 脚本文件。

    图6

    4、点击 OK

    方法2、手动配置 Gradle

    1.要手动配置 Gradle 以关联到您的原生库,你需要将 externalNativeBuild {} 块添加到模块级 build.gradle 文件中,并使用 cmake {}对其进行配置:

    图7

    2.指定可选配置

    你可以在模块级 build.gradle 文件的 defaultConfig {} 块中配置另一个 externalNativeBuild {} 块,为 CMake 指定可选参数和标志。与 defaultConfig {} 块中的其他属性类似,你也可以在构建配置中为每个产品风格重写这些属性。(一般默认即可,初级阶段不用写)

    图8

    3.指定 ABI

    默认情况下,Gradle 会针对 NDK 支持的 ABI 将你的原生库构建到单独的 .so 文件中,并将其全部打包到您的 APK 中。如果您希望 Gradle 仅构建和打包原生库的特定 ABI 配置,您可以在模块级 build.gradle 文件中使用 ndk.abiFilters 标志指定这些配置,如下所示:

    图9

    在大多数情况下,你只需要在 ndk {} 块中指定 abiFilters(如上所示),因为它会指示 Gradle 构建和打包原生库的这些版本。不过,如果您希望控制 Gradle 应当构建的配置,并独立于你希望其打包到 APK 中的配置,请在 defaultConfig.externalNativeBuild.cmake {} 块配置另一个 abiFilters 标志。Gradle 会构建这些 ABI 配置,不过仅会打包你在 defaultConfig.ndk{} 块中指定的配置。

    五、构建和运行示例应用

    点击 Run 后,Android Studio 将在您的 Android 设备或者模拟器上构建并启动一个显示文字“Hello from C++”的应用。下面的概览介绍了构建和运行示例应用时会发生的事件:

    1、Gradle 调用您的外部构建脚本 CMakeLists.txt。

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

    3、运行时,应用的 MainActivity 会使用 System.loadLibrary() 加载原生库。现在,应用可以使用库的原生函数 stringFromJNI()(我自己的工程是 sayhello()函数)。

    4、MainActivity.onCreate() 调用 stringFromJNI(),这将返回“Hello from C++”并使用这些文字更新 TextView

    六、结尾

    得去开会了,没时间写了,基础的过程就是这样,草草收个尾,有时间再写。需要注意的就是,因为好多是截图,是两个工程(一个默认就有NDK编程的,一个是自己新建然后添加C/C++代码的)截图的,可能会有混淆;还有是官方文档的资料复制来的,难免有错误。大家记得函数名和相关地方的名字同意对应就行,来看NDK编程的,肯定是Android做了有段时间了,这些应该没问题。就这样了,第一次发技术文档,代码片段全是截图,谅解。

    还有,刚刚发现的,就是应该是先在java类中声明native函数,然后再新建jni文件夹和其中的C/C++文件,再配置,是这样一个流程。新建完C++的空文件(写上包含头文件语句)并配置完CMakeLists.txt以后,文件会全部链接,此时java中的native函数的函数名会变红,光标放上去以后会显示找不到对应的函数,然后按Alt+enter,选择添加,就会自动在C++函数中添加对应的函数。

    然后,头文件<jni.h>是必须要包含的,这是系统的头文件,自己的C++文件可以不包含头文件,我这里的工程包含了,但是内容其实是空的,如下图。当然了,你自己写项目的时候,不可能像示例这么简单,肯定是要写自己的头文件的。

    示例图片

    相关文章

      网友评论

        本文标题:Android3.4 NDK编程总结

        本文链接:https://www.haomeiwen.com/subject/osbbectx.html