更新于2016-09-05的話
2016-09-01 開(kāi)學(xué)日,Android Studio 2.2RC版出了,支持CMake和ndk-build開(kāi)發(fā),而且能在穩(wěn)定的gradle插件中就可以集成cpp了,而不用像下面說(shuō)到的需要在實(shí)驗(yàn)性的插件中進(jìn)行處理。這幾天了解到很多的ndk開(kāi)發(fā)方式,總結(jié)一下:
Android Studio 2.2 + (ndk-build 或者 CMake) + classpath 'com.android.tools.build:gradle:2.2.0-rc1'
PS: 據(jù)說(shuō)以后CMake將會(huì)是主流,但是目前來(lái)說(shuō),ndk-build屬于穩(wěn)定的狀態(tài),CMake好像還處于試驗(yàn)性階段
前言
本文適合下面同學(xué)閱讀:
- 用Android Studio開(kāi)發(fā)的
- 熟悉java,但是c/cpp已經(jīng)陌生了
- 想尋找一條高效的路徑入門Android NDK
輕吐槽
在開(kāi)始之前,我必須指正一點(diǎn):在網(wǎng)上搜索出來(lái),關(guān)于Android NDK開(kāi)發(fā)入門的資料大都過(guò)時(shí)的,即便設(shè)置搜索時(shí)間為最近,搜索出來(lái)的結(jié)果大多也就可能教你如何運(yùn)行一個(gè)Hello-JNI的Demo,然后就沒(méi)了,很多資料,還是得需要你重新查找,比如 Android.mk , Application.mk 這些文件的配置說(shuō)明等等
最重要的是,在網(wǎng)上搜索出來(lái)的,Android Studio上的NDK入門資料很多都是不走官方使用說(shuō)明的(比如:最簡(jiǎn)單的,Module app上應(yīng)用的插件已經(jīng)不是com.android.application 而是 com.android.model.application了,從我自己搜索的資料來(lái)看,暫時(shí)還沒(méi)有一份提及到這一點(diǎn))
Anyway, 我自己也是摸索著入門,在這里也就和大家探討一下更加高效的入門路徑。
入門指南
在開(kāi)始指南之前,如果你是用Eclipse的話,那么網(wǎng)上隨便搜索的資料還是有用處的,但是Google都拋棄Eclipse很久了,轉(zhuǎn)為持續(xù)支持Android Studio,如果打算繼續(xù)在Android上深入的話,沒(méi)什么理由你不用Android Studio,而下文中說(shuō)到的入門路徑全部都是在Android Studio上的操作,不喜請(qǐng)繞步。
從官方入門Demo學(xué)起
從官方 Android Studio 入門demo看起,可能你會(huì)說(shuō)英文難看,但是我覺(jué)得在難看之前,你更應(yīng)該關(guān)心的是質(zhì)量,如果有同等質(zhì)量的中文翻譯,那么看中文版也是可以的,但是目前為止,官方的英文原版還是最好的,而且最近官網(wǎng)更新了頁(yè)面風(fēng)格,文檔頓時(shí)感覺(jué)很好看了。在這個(gè)demo中,你將學(xué)會(huì):
- 應(yīng)該怎么配置NDK開(kāi)發(fā)環(huán)境
- 如何在AndroidStudio上創(chuàng)建一個(gè)NDK開(kāi)發(fā)demo
- 如何修改項(xiàng)目配置(Project Module等等地方的gradle腳本和配置),從而令你的項(xiàng)目JNI部分可以跑起來(lái)
- 添加JNI代碼(不是網(wǎng)上通篇一律的用
javah的方法) - 如何debugJNI代碼
- 最后一頁(yè)提供了各種后續(xù)上手學(xué)習(xí)的內(nèi)容,比如NDK的詳細(xì)配置(Android.mk等),官方demo等
詳細(xì)了解NDK Gradle Plugin
在上面官方demo運(yùn)行成功之后,重新仔細(xì)閱讀一下,運(yùn)行Demo所用的 NDK Gradle Plugin (第一步中提及到)的使用說(shuō)明,只有更加了解這個(gè)gradle配置說(shuō)明,你才不會(huì)一開(kāi)始就卡在為什么demo跑不起來(lái),以及要怎么定義NDK的調(diào)試模式等等各方面的內(nèi)容
另外我附一下:官方的app/build.gradle 的部分內(nèi)容截圖,圖中紅色的都是和我們平時(shí)用的有區(qū)別,需要更改過(guò)來(lái)的,具體的還是務(wù)必詳細(xì)認(rèn)真仔細(xì)耐心...地閱讀NDK Gradle Plugin

到這里,你大概掌握到
- 如何在Andorid Studio上運(yùn)行一個(gè)NDK app
- 如果你深入閱讀的話,你可能還掌握到如何創(chuàng)建一個(gè)Andorid Native Library(類似于Android Library),如果你公司夠人手的話,那么分工開(kāi)來(lái)還是很舒服的:熟悉java的負(fù)責(zé)app開(kāi)發(fā)(app module),熟悉c/cpp的負(fù)責(zé)NDK開(kāi)發(fā)(Android Native Library)
詳細(xì)了解NDK的內(nèi)容
接下來(lái)的學(xué)習(xí)路徑建議你重點(diǎn)閱讀一下官網(wǎng)的 Get Start With NDK ,Android.mk , Application.mk等的使用說(shuō)明都在這里面了。這里面章節(jié)可能多一點(diǎn),但是最起碼需要閱讀到Libraries吧。部分章節(jié)會(huì)設(shè)計(jì)到一些c/cpp 方面的,學(xué)習(xí)時(shí)可以酌情跳過(guò),我們先大概了解整個(gè)流程,后面學(xué)習(xí)好c/cpp后,重新在回來(lái)看幾次

我這里順帶說(shuō)一下:在 Concepts 章節(jié)中,存在下面說(shuō)明,估計(jì)大家應(yīng)該都明白 Andorid.mk 和 Application.mk 是什么鬼,以及在AS上是否需要配置了

友情提示:Android.mk 以及 Application.mk 都是僅僅在你用 命令行 的方式編譯生成.so .a的時(shí)候生效,在你使用Android Studio的時(shí)候,官方已經(jīng)推出了更加好用的NDK Gradle Plugin,因此
- 采用命令行 + Android.mk + Application.mk 已經(jīng)算是屬于舊時(shí)代的構(gòu)建方式
- Android Studio + NDK Gradle Plugin 算是新的構(gòu)建方式,不過(guò)新的東西嘛,總是有點(diǎn)什么不穩(wěn)定之類的
學(xué)習(xí)的時(shí)候自己酌情看咯,不過(guò)時(shí)間緊迫的話,直接學(xué)習(xí)Android Studio + NDK Gradle Plugin更好
閱讀官方Demo
經(jīng)過(guò)上面幾步的學(xué)習(xí),你就能掌握如何在Android Studio上使用NDK開(kāi)發(fā)JNI,但是相信你可能還是存在一些疑問(wèn),不要緊,可以到 官方的NDK Sample中看一下官方是怎么寫的,通過(guò)閱讀別人的寫法,可能突然就解決掉你的問(wèn)題
盡可能循環(huán)上面幾步
視個(gè)人情況,你可以循環(huán)上面的學(xué)習(xí)路徑幾次,溫故知新。
- 比如:我在重新閱讀的過(guò)程中,了解到以前開(kāi)發(fā)的.so庫(kù),基本是靠
ndk-build命令,以及Android.mk和Application.mk文件的配置來(lái)進(jìn)行生成.so庫(kù)的,但是現(xiàn)在as采用gradle構(gòu)建之后,其實(shí)已經(jīng)在某種程度上不在需要使用上面的命令和文件配置進(jìn)行生成.so庫(kù)了,直接用官方的NDK Gradle Plugin即可 - 比如:在學(xué)習(xí)NDK Gradle Plugin時(shí),app的
build.gradle中,官方的使用說(shuō)明上存在下面的內(nèi)容
CFlags.add("-DCUSTOM_DEFINE")
cppFlags.add("-DCUSTOM_DEFINE")
ldFlags.add("-L/custom/lib/path")
ldLibs.add("log")
stl = "stlport_static"
當(dāng)時(shí)你可能沒(méi)搞懂這幾個(gè)配置是什么意思,但是在經(jīng)過(guò)上面 詳細(xì)了解NDK的內(nèi)容 的學(xué)習(xí)之后,你重新看回這里,就明白了
// 1. CFlags和cppFlags都是可選配置
// 2. CFlags和cppFlags都是用于指定額外的宏定義或者編譯選項(xiàng)
// 3. CFlags:同時(shí)生效于c和cpp源文件
// 4. cppFlags:僅僅只生效于cpp源文件,并且是在CFlags之后生效
// 5. 特別地:在android-ndk-1.5-r1
// 1. CFlags僅僅只針對(duì)c源文件生效
// 2. cppFlags同時(shí)生效于c和cpp源文件
CFlags.add("-DCUSTOM_DEFINE") // (可選)
cppFlags.add("-DCUSTOM_DEFINE") // (可選)在構(gòu)建c++源文件的時(shí)候傳入,在編譯器構(gòu)建命令行中最后出現(xiàn)
ldFlags.add("-L/custom/lib/path")
// 構(gòu)建時(shí),需要用到的額外鏈接庫(kù)
ldLibs.add("log")
// 打包的時(shí)候,需要包含的標(biāo)準(zhǔn)庫(kù)
stl = "stlport_static"
重新學(xué)習(xí)C/CPP
剩下的就是在重新學(xué)習(xí)c/cpp的使用了,關(guān)于C++的學(xué)習(xí)書(shū)籍推薦,經(jīng)過(guò)好友推薦,目前我在看是 《c++ primer plus 第六版》,還在閱讀中,目前感覺(jué)還可以
總結(jié)
上面是我自己學(xué)習(xí)NDK時(shí)的入門路徑,也是滾打滾著學(xué),后來(lái)總結(jié)出這樣子的路徑算是比較快吧,如果想買書(shū)學(xué)習(xí)NDK方面的話,其實(shí)不太推薦,粗略看了一下,一些相關(guān)書(shū)籍的目錄,都是很舊的了,完全沒(méi)跟上時(shí)代的發(fā)展,不過(guò)如果你已經(jīng)掌握了大致的開(kāi)發(fā)過(guò)程,那么買本書(shū)重新系統(tǒng)地review一下,還是很好的
后記(2016-08-16)
今天偶然發(fā)現(xiàn)了極客學(xué)院中存在一份很詳細(xì)的JNI使用教程,大家可以看看http://wiki.jikexueyuan.com/project/jni-ndk-developer-guide/