Android3.4 NDK编程总结

最近项目需要,要做串口的通信,涉及到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++文件可以不包含头文件,我这里的工程包含了,但是内容其实是空的,如下图。当然了,你自己写项目的时候,不可能像示例这么简单,肯定是要写自己的头文件的。

示例图片
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容