NDK(Native Development Kit)是一套工具集,容許你在Android應用中嵌入c或c++。 java
使用NDK的好處主要有如下4點:android
安全:因爲apk的java層代碼很容易被反編譯,而C/C++庫反匯難度較大。c++
重用:能夠方便地使用現存的開源庫。大部分現存的開源庫都是用C/C++代碼編寫的。shell
效率:將要求高性能的應用邏輯使用C開發,從而提升應用程序的執行效率。android-studio
移植:用C/C++寫得庫能夠方便在其餘的嵌入式平臺上再次使用。安全
這個shell構建腳本是NDK的核心。bash
本地共享庫,本地代碼通過編譯後生成的二進制文件.so``.dll
markdown
本地靜態庫,用來鏈接其餘代碼庫架構
Java平臺的重要特性,容許Java代碼和其餘本地語言進行交互,如c/c++app
定義了二進制文件(尤爲是.so文件)如何運行在相應的系統平臺上。在Android系統上,每一種CPU架構對應一個ABI:
armeabi(默認),armeabi-v7a,x86,mips,arm64- v8a,mips64,x86_64。
必備組件,在jni文件夾下,用來描述NDK構建系統。ndk-build腳本從該文件中讀取定義的模塊,名字和須要編譯的資源文件等。
可選構建文件,和Android.mk同樣,放在jni目錄下,這個文件列舉和描述了你應用模塊所需的東西,如指定的ABIs編譯平臺,工具鏈等。
建立Android項目,建立java文件,並聲明本地方法
編譯,獲得.class
文件
使用javah命令,生成jni目錄和.h
頭文件
在jni目錄下建立c/c++文件,引入頭文件,編寫本地方法的實現
建立Android.mk,用來描述你要在jni目錄下生成的本地庫
建立Application.mk(可選)來配置目標ABIs, toolchain, release/debug mode, STL等
使用ndk-build腳本將c/c++文件編譯成本地庫.so
打包,運行程序
如今Anroid Studio已經支持全新的NDK使用,舊的方法已經被標爲廢棄。但新方法還在實驗階段,因此舊方法依舊重要!
public class JNIHelper {
public static native String getStringFromNative();
}
生成地址:YourApplication\app\build\intermediates\classes\debug
打開termianl執行:
javah -d jni -classpath /Users/DeanGuo/TestNDK/app/build/intermediates/classes/debug com.dean.testndk. JNIHelper
成功後會生成一個jni目錄,目錄下會有一個com_dean_testndk_JNIHelper.h
頭文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_dean_testndk_JNIHelper */
#ifndef _Included_com_dean_testndk_JNIHelper
#define _Included_com_dean_testndk_JNIHelper
#ifdef __cplusplus
extern "C" {
#endif
/* * Class: com_dean_testndk_JNIHelper * Method: getStringFromNative * Signature: ()Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_com_dean_testndk_JNIHelper_getStringFromNative
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
#include "com_dean_testndk_JNIHelper.h"
JNIEXPORT jstring JNICALL Java_com_dean_testndk_JNIHelper_getStringFromNative
(JNIEnv * env, jobject jclass) {
return (*env)->NewStringUTF(env, "return from native c");
}
傳統方法是使用Android.mk,Application.mk進行配置,最後經過ndk-build腳原本生產.so本地庫。
使用Android Studio能夠將配置和執行腳本的工做都交給Gradle。
打開工程的build.gradle配置文件,在defaultConfig中添加ndk
標籤用來配置.so的名字和abi架構,以下:
defaultConfig {
applicationId "com.dean.testndk"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk{
moduleName "test" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //指定abi體系結構下的so庫,不指定使用默認方案
// stl "stlport_shared"
// ldLibs "log", "z", "m"
// cFlags "-I/some/include/path"
}
}
目前須要在grade.properties中添加
android.useDeprecatedNdk=true
(由於目前Android Studio推出了新的ndk支持,下一篇會講到)
生成好的so文件能夠在app/build/intermediates/ndk/debug/lib
中看到。
本地庫已經生成,如今就經過代碼來加載使用了:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("test");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("ndk_log : ", JNIHelper.getStringFromNative());
}
}
執行後控制檯打印:I/ndk_log :: return from native c
相比Eclipse,使用Android Stuido更加直觀方便。「基本」能夠忽略Android.mk,Application.mk的編寫與配置。而新版的NDK支持將更增強大,將會在下一篇文章介紹。