更新于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好像還處于試驗性階段
前言
本文適合下面同學閱讀:
- 用Android Studio開發的
- 熟悉java,但是c/cpp已經陌生了
- 想尋找一條高效的路徑入門Android NDK
輕吐槽
在開始之前,我必須指正一點:在網上搜索出來,關于Android NDK開發入門的資料大都過時的,即便設置搜索時間為最近,搜索出來的結果大多也就可能教你如何運行一個Hello-JNI的Demo,然后就沒了,很多資料,還是得需要你重新查找,比如 Android.mk
, Application.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
到這里,你大概掌握到
- 如何在Andorid Studio上運行一個NDK app
- 如果你深入閱讀的話,你可能還掌握到如何創建一個Andorid Native Library(類似于Android Library),如果你公司夠人手的話,那么分工開來還是很舒服的:熟悉java的負責app開發(app module),熟悉c/cpp的負責NDK開發(Android Native Library)
詳細了解NDK的內容
接下來的學習路徑建議你重點閱讀一下官網的 Get Start With NDK ,Android.mk
, Application.mk
等的使用說明都在這里面了。這里面章節可能多一點,但是最起碼需要閱讀到Libraries吧。部分章節會設計到一些c/cpp 方面的,學習時可以酌情跳過,我們先大概了解整個流程,后面學習好c/cpp后,重新在回來看幾次
我這里順帶說一下:在 Concepts 章節中,存在下面說明,估計大家應該都明白 Andorid.mk
和 Application.mk
是什么鬼,以及在AS上是否需要配置了
友情提示: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中看一下官方是怎么寫的,通過閱讀別人的寫法,可能突然就解決掉你的問題
盡可能循環上面幾步
視個人情況,你可以循環上面的學習路徑幾次,溫故知新。
- 比如:我在重新閱讀的過程中,了解到以前開發的.so庫,基本是靠
ndk-build
命令,以及Android.mk
和Application.mk
文件的配置來進行生成.so庫的,但是現在as采用gradle構建之后,其實已經在某種程度上不在需要使用上面的命令和文件配置進行生成.so庫了,直接用官方的NDK Gradle Plugin即可 - 比如:在學習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/