Android NDK 開(kāi)發(fā)入門指南

更新于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é)閱讀:

  1. 用Android Studio開(kāi)發(fā)的
  2. 熟悉java,但是c/cpp已經(jīng)陌生了
  3. 想尋找一條高效的路徑入門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.mkApplication.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

Paste_Image.png

到這里,你大概掌握到

  1. 如何在Andorid Studio上運(yùn)行一個(gè)NDK app
  2. 如果你深入閱讀的話,你可能還掌握到如何創(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 NDKAndroid.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)看幾次

3.png

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

Paste_Image.png

友情提示: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í)路徑幾次,溫故知新。

  1. 比如:我在重新閱讀的過(guò)程中,了解到以前開(kāi)發(fā)的.so庫(kù),基本是靠ndk-build命令,以及Android.mkApplication.mk文件的配置來(lái)進(jìn)行生成.so庫(kù)的,但是現(xiàn)在as采用gradle構(gòu)建之后,其實(shí)已經(jīng)在某種程度上不在需要使用上面的命令和文件配置進(jìn)行生成.so庫(kù)了,直接用官方的NDK Gradle Plugin即可
  2. 比如:在學(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/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容