NDK產(chǎn)生背景
Android平臺(tái)從誕生起奸汇,就已經(jīng)支持C件舵、C++開發(fā)。眾所周知抚太,Android的SDK基于Java實(shí)現(xiàn),這意味著基于Android SDK進(jìn)行開發(fā)的第三方應(yīng)用都必須使用Java語(yǔ)言昔案。但這并不等同于“第三方應(yīng)用只能使用Java”尿贫。在Android SDK首次發(fā)布時(shí),Google就宣稱其虛擬機(jī)Dalvik支持JNI編程方式踏揣,也就是第三方應(yīng)用完全可以通過(guò)JNI調(diào)用自己的C動(dòng)態(tài)庫(kù)庆亡,即在Android平臺(tái)上,“Java+C”的編程方式是一直都可以實(shí)現(xiàn)的捞稿。
不過(guò)又谋,Google也表示,使用原生SDK編程相比Dalvik虛擬機(jī)也有一些劣勢(shì)娱局,Android SDK文檔里彰亥,找不到任何JNI方面的幫助。即使第三方應(yīng)用開發(fā)者使用JNI完成了自己的C動(dòng)態(tài)鏈接庫(kù)(so)開發(fā)衰齐,但是so如何和應(yīng)用程序一起打包成apk并發(fā)布任斋?這里面也存在技術(shù)障礙。比如程序更加復(fù)雜耻涛,兼容性難以保障废酷,無(wú)法訪問(wèn)Framework API瘟檩,Debug難度更大等。開發(fā)者需要自行斟酌使用澈蟆。
于是NDK就應(yīng)運(yùn)而生了墨辛。NDK全稱是Native Development Kit。
NDK的發(fā)布趴俘,使“Java+C”的開發(fā)方式終于轉(zhuǎn)正睹簇,成為官方支持的開發(fā)方式。NDK將是Android平臺(tái)支持C開發(fā)的開端寥闪。
為什么使用NDK
- 代碼的保護(hù)带膀。由于apk的java層代碼很容易被反編譯,而C/C++庫(kù)反匯難度較大橙垢。
- 可以方便地使用現(xiàn)存的開源庫(kù)。大部分現(xiàn)存的開源庫(kù)都是用C/C++代碼編寫的伦糯。
- 提高程序的執(zhí)行效率柜某。將要求高性能的應(yīng)用邏輯使用C開發(fā),從而提高應(yīng)用程序的執(zhí)行效率敛纲。
- 便于移植喂击。用C/C++寫得庫(kù)可以方便在其他的嵌入式平臺(tái)上再次使用。
配置環(huán)境
下載NDK淤翔,NDK下載路徑翰绊。
Windows下的是一個(gè)自解壓文件,下載完成后雙擊運(yùn)行旁壮,文件會(huì)自解壓到當(dāng)前目錄监嗜,記住該目錄地址,配置AndroidStudio時(shí)需要使用到這個(gè)地址打開AndroidStudio抡谐,F(xiàn)ile -> Project Structure打開對(duì)話框裁奇,在對(duì)話框中輸入NDK路徑(上面的解壓路徑)
開啟NDK之旅
1.新建JNIDemo工程,打開MainActivity.java
文件麦撵,在類內(nèi)輸入下面代碼后刽肠,Build -> Make Project
public native String getStringFromNative();
2.在Terminal輸入命令
cd app\src\main
javah -d jni -classpath C:\AndroidSdk\platforms\android-23\android.jar;..\..\build\intermediates\classes\debug com.sentu.jnidemo.MainActivity
就會(huì)發(fā)現(xiàn)在main目錄下多了一個(gè)jni文件夾,里面有生成好的頭文件
3.在jni目錄下創(chuàng)建一個(gè).c文件免胃,實(shí)現(xiàn)頭文件里聲明的方法
#include "com_sentu_jnidemo_MainActivity.h"
JNIEXPORT jstring JNICALL Java_com_sentu_jnidemo_MainActivity_getStringFromNative(JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env, "I'm comes from to Native Function!");
}
4.在 local.properties 文件中設(shè)置ndk的路徑
ndk.dir=C\:\\AndroidSdk\\android-ndk-r10e
5.在MainActivity.java文件中添加如下代碼
public class MainActivity extends Activity {
public native String getStringFromNative();
static {
System.loadLibrary("MyJni");
}
TextView info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
info = (TextView) findViewById(R.id.info);
info.setText(getStringFromNative());
}
}
6.運(yùn)行音五,查看效果
這個(gè)時(shí)候可能會(huì)出現(xiàn)一個(gè)問(wèn)題
Error:(13, 0) Error: NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin. For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental. Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.
解決方案: 在gradle.properties
中添加android.useDeprecatedNdk=true