Android NDK 开发入门指南

更新于2016-09-05的话

2016-09-01 开学日,Android Studio 2.2RC版出了,支持CMake和ndk-build开发,而且能在稳定的gradle插件中就可以集成cpp了,而不用像下面说到的需要在实验性的插件中进行处理。这几天了解到很多的ndk开发方式,总结一下:

Android Studio 2.2 + (ndk-build 或者 CMake) + classpath 'com.android.tools.build:gradle:2.2.0-rc1'  

PS: 据说以后CMake将会是主流,但是目前来说,ndk-build属于稳定的状态,CMake好像还处于试验性阶段

前言

本文适合下面同学阅读:

  1. 用Android Studio开发的
  2. 熟悉java,但是c/cpp已经陌生了
  3. 想寻找一条高效的路径入门Android NDK

轻吐槽

在开始之前,我必须指正一点:在网上搜索出来,关于Android NDK开发入门的资料大都过时的,即便设置搜索时间为最近,搜索出来的结果大多也就可能教你如何运行一个Hello-JNI的Demo,然后就没了,很多资料,还是得需要你重新查找,比如 Android.mkApplication.mk 这些文件的配置说明等等

最重要的是,在网上搜索出来的,Android Studio上的NDK入门资料很多都是不走官方使用说明的(比如:最简单的,Module app上应用的插件已经不是com.android.application 而是 com.android.model.application了,从我自己搜索的资料来看,暂时还没有一份提及到这一点)

Anyway, 我自己也是摸索着入门,在这里也就和大家探讨一下更加高效的入门路径。

入门指南

在开始指南之前,如果你是用Eclipse的话,那么网上随便搜索的资料还是有用处的,但是Google都抛弃Eclipse很久了,转为持续支持Android Studio,如果打算继续在Android上深入的话,没什么理由你不用Android Studio,而下文中说到的入门路径全部都是在Android Studio上的操作,不喜请绕步。

从官方入门Demo学起

官方 Android Studio 入门demo看起,可能你会说英文难看,但是我觉得在难看之前,你更应该关心的是质量,如果有同等质量的中文翻译,那么看中文版也是可以的,但是目前为止,官方的英文原版还是最好的,而且最近官网更新了页面风格,文档顿时感觉很好看了。在这个demo中,你将学会:

  • 应该怎么配置NDK开发环境
  • 如何在AndroidStudio上创建一个NDK开发demo
  • 如何修改项目配置(Project Module等等地方的gradle脚本和配置),从而令你的项目JNI部分可以跑起来
  • 添加JNI代码(不是网上通篇一律的用javah的方法)
  • 如何debugJNI代码
  • 最后一页提供了各种后续上手学习的内容,比如NDK的详细配置(Android.mk等),官方demo等

详细了解NDK Gradle Plugin

在上面官方demo运行成功之后,重新仔细阅读一下,运行Demo所用的 NDK Gradle Plugin (第一步中提及到)的使用说明,只有更加了解这个gradle配置说明,你才不会一开始就卡在为什么demo跑不起来,以及要怎么定义NDK的调试模式等等各方面的内容

另外我附一下:官方的app/build.gradle 的部分内容截图,图中红色的都是和我们平时用的有区别,需要更改过来的,具体的还是务必详细认真仔细耐心...地阅读NDK Gradle Plugin

Paste_Image.png

到这里,你大概掌握到

  1. 如何在Andorid Studio上运行一个NDK app
  2. 如果你深入阅读的话,你可能还掌握到如何创建一个Andorid Native Library(类似于Android Library),如果你公司够人手的话,那么分工开来还是很舒服的:熟悉java的负责app开发(app module),熟悉c/cpp的负责NDK开发(Android Native Library)

详细了解NDK的内容

接下来的学习路径建议你重点阅读一下官网的 Get Start With NDKAndroid.mkApplication.mk等的使用说明都在这里面了。这里面章节可能多一点,但是最起码需要阅读到Libraries吧。部分章节会设计到一些c/cpp 方面的,学习时可以酌情跳过,我们先大概了解整个流程,后面学习好c/cpp后,重新在回来看几次

3.png

我这里顺带说一下:在 Concepts 章节中,存在下面说明,估计大家应该都明白 Andorid.mkApplication.mk 是什么鬼,以及在AS上是否需要配置了

Paste_Image.png

友情提示:Android.mk 以及 Application.mk 都是仅仅在你用 命令行 的方式编译生成.so .a的时候生效,在你使用Android Studio的时候,官方已经推出了更加好用的NDK Gradle Plugin,因此

  • 采用命令行 + Android.mk + Application.mk 已经算是属于旧时代的构建方式
  • Android Studio + NDK Gradle Plugin 算是新的构建方式,不过新的东西嘛,总是有点什么不稳定之类的

学习的时候自己酌情看咯,不过时间紧迫的话,直接学习Android Studio + NDK Gradle Plugin更好

阅读官方Demo

经过上面几步的学习,你就能掌握如何在Android Studio上使用NDK开发JNI,但是相信你可能还是存在一些疑问,不要紧,可以到 官方的NDK Sample中看一下官方是怎么写的,通过阅读别人的写法,可能突然就解决掉你的问题

尽可能循环上面几步

视个人情况,你可以循环上面的学习路径几次,温故知新。

  1. 比如:我在重新阅读的过程中,了解到以前开发的.so库,基本是靠ndk-build命令,以及Android.mkApplication.mk文件的配置来进行生成.so库的,但是现在as采用gradle构建之后,其实已经在某种程度上不在需要使用上面的命令和文件配置进行生成.so库了,直接用官方的NDK Gradle Plugin即可
  2. 比如:在学习NDK Gradle Plugin时,app的build.gradle中,官方的使用说明上存在下面的内容
    CFlags.add("-DCUSTOM_DEFINE")
    cppFlags.add("-DCUSTOM_DEFINE")
    ldFlags.add("-L/custom/lib/path")
    ldLibs.add("log")
    stl = "stlport_static"

当时你可能没搞懂这几个配置是什么意思,但是在经过上面 详细了解NDK的内容 的学习之后,你重新看回这里,就明白了

    // 1. CFlags和cppFlags都是可选配置
    // 2. CFlags和cppFlags都是用于指定额外的宏定义或者编译选项
    // 3. CFlags:同时生效于c和cpp源文件
    // 4. cppFlags:仅仅只生效于cpp源文件,并且是在CFlags之后生效
    // 5. 特别地:在android-ndk-1.5-r1
    //     1. CFlags仅仅只针对c源文件生效
    //     2. cppFlags同时生效于c和cpp源文件
    CFlags.add("-DCUSTOM_DEFINE")   // (可选)
    cppFlags.add("-DCUSTOM_DEFINE")   // (可选)在构建c++源文件的时候传入,在编译器构建命令行中最后出现

    ldFlags.add("-L/custom/lib/path")

    // 构建时,需要用到的额外链接库
    ldLibs.add("log")

    // 打包的时候,需要包含的标准库
    stl = "stlport_static" 

重新学习C/CPP

剩下的就是在重新学习c/cpp的使用了,关于C++的学习书籍推荐,经过好友推荐,目前我在看是 《c++ primer plus 第六版》,还在阅读中,目前感觉还可以

总结

上面是我自己学习NDK时的入门路径,也是滚打滚着学,后来总结出这样子的路径算是比较快吧,如果想买书学习NDK方面的话,其实不太推荐,粗略看了一下,一些相关书籍的目录,都是很旧的了,完全没跟上时代的发展,不过如果你已经掌握了大致的开发过程,那么买本书重新系统地review一下,还是很好的

后记(2016-08-16)

今天偶然发现了极客学院中存在一份很详细的JNI使用教程,大家可以看看http://wiki.jikexueyuan.com/project/jni-ndk-developer-guide/

推荐阅读更多精彩内容