看前必讀
- 讀完本章绽慈,你可以掌握NDK、JNI的概念及其開(kāi)發(fā)流程辈毯。
- 閱讀時(shí)坝疼,不必糾結(jié)于讀不懂的代碼結(jié)構(gòu),后面的教程 都會(huì)講到的谆沃。
一钝凶、為何要學(xué)習(xí)NDK?
- 代碼的保護(hù)唁影。Android APK的Java層代碼很容易被反編譯耕陷,但C/C++庫(kù)反編譯難度較大。
- 可以方便地使用現(xiàn)存的開(kāi)源庫(kù)据沈。大部分現(xiàn)存的開(kāi)源庫(kù)都是用C/C++代碼編寫(xiě)的哟沫。
- 提高程序的執(zhí)行效率。將要求高性能的應(yīng)用邏輯使用C開(kāi)發(fā)锌介,從而提高應(yīng)用程序的執(zhí)行效率嗜诀。
- 便于移植猾警。用C/C++寫(xiě)的庫(kù)可以方便在其他的嵌入式平臺(tái)上再次使用。
二隆敢、先知道什么是JNI
JNI(Java Native Interface)是Java語(yǔ)言提供的Java和C/C++互相溝通的機(jī)制发皿,可以實(shí)現(xiàn):
- java調(diào)用本地的C/C++代碼
- 本地的C/C++代碼也可以調(diào)用java代碼
三、開(kāi)發(fā)JNI程序的簡(jiǎn)化流程
- 編寫(xiě)Java Code拂蝎,如下例子:
/**
* 加載lavor本地共享庫(kù)到內(nèi)存中
*/
static {
System.loadLibrary("lavor");
}
/**
* 定義本地方法對(duì)應(yīng)的Java方法
*
* @return
*/
public native String getString();
- 編寫(xiě)C/C++穴墅,如下例子:
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_com_lavor_ndklearning_MainActivity_getString(JNIEnv *env, jobject instance) {
return (*env)->NewStringUTF(env, "這是我的c程序代碼");
}
- 編譯 C/C++ Code,成功并得到本地共享庫(kù)温自。
小知識(shí)
- 本地共享庫(kù)是Linux下的叫法玄货,文件擴(kuò)展名是.so,windows下叫動(dòng)態(tài)鏈接庫(kù)捣作,文件擴(kuò)展名是.dll誉结。
- <a name="001" id="001" >C /C++的跨平臺(tái)性是以犧牲編譯時(shí)間以及編譯難度為代價(jià)的。(這里的編譯難度是指為適應(yīng)不同平臺(tái)而做的編譯過(guò)程的調(diào)整)</a>
- Java的一次編譯到處運(yùn)行券躁,是以犧牲運(yùn)行效率為代價(jià)的惩坑。
- 編譯并打包Java。
把本地共享庫(kù)(.so文件)放置到Java項(xiàng)目的指定目錄也拜,一般是libs文件夾以舒。然后編譯Java代碼即可打包運(yùn)行。
小知識(shí)
- Android項(xiàng)目中慢哈,.so文件存放地址為libs/armeabi蔓钟。(armeabi是對(duì)應(yīng)的平臺(tái),下一章將會(huì)詳細(xì)介紹)
四卵贱、NDK概述
NDK(Native Development Kit)是Google為Android進(jìn)行本地開(kāi)發(fā)而放出的一個(gè)本地開(kāi)發(fā)工具滥沫, 包括Android的Native API、公共庫(kù)以及編譯工具键俱。其實(shí)說(shuō)白就是Google為方便Android程序猿開(kāi)發(fā)JNI程序兰绣,而提供的便捷工具。
補(bǔ)充兩點(diǎn)
- NDK處在JNI開(kāi)發(fā)流程中的編譯環(huán)節(jié)(第三编振、四步)缀辩。針對(duì)不同的平臺(tái),NDK可以全自動(dòng)編譯出對(duì)應(yīng)可運(yùn)行的本地共享庫(kù)踪央,并可將對(duì)應(yīng)的.so文件和應(yīng)用程序一起打包成apk發(fā)布臀玄。(這時(shí),跨平臺(tái)編譯C/C++的難度指數(shù)降為0畅蹂。<a href="#001">不明白請(qǐng)猛擊</a>)
- NDK需要Android 1.5版本以上的支持健无。
五、開(kāi)發(fā)NDK程序的流程
這個(gè)開(kāi)發(fā)流程大致與JNI的開(kāi)發(fā)流程差不多:
- SDK開(kāi)發(fā)液斜。編寫(xiě)Java代碼累贤,調(diào)用各種Android的API實(shí)現(xiàn)功能募胃,編寫(xiě)含有native關(guān)鍵字的代碼開(kāi)始JNI。
- JNI開(kāi)發(fā)畦浓。按照 JNI編碼規(guī)范,編寫(xiě)與Java交互的本地代碼(一般就是數(shù)據(jù)類型的轉(zhuǎn)換检疫,把 C/C++的數(shù)據(jù)類轉(zhuǎn)換成Java能識(shí)別的讶请,或反過(guò)來(lái))。
- C/C++開(kāi)發(fā)屎媳。編碼實(shí)現(xiàn)業(yè)務(wù)邏輯夺溢,或調(diào)用NDK提供的本地API或庫(kù),完成Android平臺(tái)上特定功能的開(kāi)發(fā)烛谊、封裝风响。
- NDK編譯,編寫(xiě).mk文件丹禀,編譯調(diào)試状勤,最后修改.mk文件,針對(duì)特定的平臺(tái)(ARM/x86)做編譯結(jié)果的優(yōu)化双泪。
- 最后就是SDK編譯持搜、打包,上真機(jī)調(diào)試了...
注意啦焙矛!此文并非原創(chuàng)葫盼,算是對(duì)一波優(yōu)秀文章的總結(jié)吧。筆者希望通過(guò)這種方式激勵(lì)自己學(xué)習(xí)村斟,也期待可以幫到正在學(xué)習(xí)NDK的你贫导。歡迎指出本文的BUG,共勉s№铩:⒌啤!H沼А钱反!
參考資料