NDK開發(fā),其實(shí)是為了項(xiàng)目需要調(diào)用底層的一些C/C++的一些東西;另外就是為了效率更加高些。如果你在Eclipse+ADT下開發(fā)過NDK就能體會(huì)到要么是配置NDK還要下載Cygwin,配置Cygwin ,然后需要編譯生成,相當(dāng)?shù)牡疤?。要么是直接用Eclipse開發(fā),但是前期配置也是一堆;真心蛋疼。但是現(xiàn)在在AS上Eclipse能做到的這邊都OK,這邊有的Eclipse上沒有的,而且Google親生的支持下只會(huì)越來越比Eclipse下開發(fā)NDK更加牛逼,所以你還不準(zhǔn)備上手嗎?
在AS開發(fā)NDK JNI也需要配置,不過相當(dāng)Easy。第一步就是去官方下載個(gè)NDK包就可以了,像我的直接放在D盤就行了。關(guān)于怎么下載安裝看這里AD NDK會(huì)有介紹。
第二步就是就是直接寫代碼了。哈哈,你沒聽錯(cuò),是這樣的,方便吧?至于下載下來的NDK怎么和AS工程關(guān)聯(lián),也就是一行配置的問題,后文有說明帶你一步一步體驗(yàn)。
But,還是要有個(gè)but,Android Studio還不是個(gè)壯年,尤其在NDK開發(fā)中,所以本文只是工具性的演示,實(shí)質(zhì)是教會(huì)大家NDK開發(fā)。
Let’s Go?。?!
在AS中新建一個(gè)Project,然后再新建一個(gè)class為NdkJniUtils,在內(nèi)部聲明native方法(jni使用的定義,后面系列教程會(huì)細(xì)說)。
package io.github.yanbober.ndkapplication;
public class NdkJniUtils {
public native String getCLanguageString();
}
在工程主文件Activity中寫入如下代碼調(diào)運(yùn)JNI的東西顯示在UI上。
public class MainActivity extends ActionBarActivity {
private TextView mTextView;
@Override
protected? onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) .findViewById(R.id.test);
NdkJniUtils jni =? NdkJniUtils();
mTextView.setText(jni.getCLanguageString());
}
}
然后build project得到其中中間文件,我們關(guān)注的是.class文件。編譯OK以后生成的class文件在AS工程的如下目錄:
NDKApplication\app\build\intermediates\classes\debug
然后接下來的步驟就是根據(jù)生成的class文件,利用javah生成對(duì)應(yīng)的 .h頭文件。
點(diǎn)開AS的Terminal標(biāo)簽,默認(rèn)進(jìn)入到該項(xiàng)目的app文件夾下。我在windows平臺(tái)下輸入如下命令跳轉(zhuǎn)到class中間文件生成路徑:
xxxxx\app> cd build\intermediates\classes\debug
然后執(zhí)行如下javah命令生成h文件。
xxxxx\debug> javah -jni io.github.yanbober.ndkapplication.NdkJniUtils
執(zhí)行完之后你可以在文件夾NDKApplication\app\build\intermediates\classes\debug下看見生成的 .h頭文件為:
io_github_yanbober_ndkapplication_NdkJniUtils.h
其內(nèi)容為:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class io_github_yanbober_ndkapplication_NdkJniUtils */
#ifndef _Included_io_github_yanbober_ndkapplication_NdkJniUtils
#define _Included_io_github_yanbober_ndkapplication_NdkJniUtils
#ifdef __cplusplus
extern? {
#endif
/*
* Class:? ? io_github_yanbober_ndkapplication_NdkJniUtils
* Method:? ? getCLanguageString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_io_github_yanbober_ndkapplication_NdkJniUtils_getCLanguageString
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
在工程的main目錄下新建一個(gè)名字為jni的目錄,然后將剛才的 .h文件剪切過來。在jni目錄下新建一個(gè)c文件,隨意取名,我的叫jnitest.c 。然后編輯代碼如下(后面會(huì)解釋啥意思,這里重在工具使用):
#include "io_github_yanbober_ndkapplication_NdkJniUtils.h"
/*
* Class:? ? io_github_yanbober_ndkapplication_NdkJniUtils
* Method:? ? getCLanguageString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_io_github_yanbober_ndkapplication_NdkJniUtils_getCLanguageString
(JNIEnv *env, jobject ){
return (*env)->NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");
}
接下來在工程的local.properties文件中添加NDK路徑(上面下載好的那個(gè)NDK),類似其中的SDK路徑一樣,我的添加后如下:
sdk.dir=D\:\\AndroidStdioSDK\\sdk
#add by 工匠若水
ndk.dir=D\:\\AndroidStdioSDK\\android-ndk-r10d-bit
接下來在app module目錄下的build.gradle中設(shè)置庫文件名(生成的so文件名)。找到gradle文件的defaultConfig這項(xiàng),在里面添加如下內(nèi)容:
defaultConfig {
ndk{
moduleName "YanboberJniLibName"? ? ? ? //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86"? //輸出指定三種abi體系結(jié)構(gòu)下的so庫。目前可有可無。
}
}
現(xiàn)在生成的so庫名字也有了,那就去代碼的NdkJniUtils java文件添加靜態(tài)初始化load代碼,添加如下:
static {
System.loadLibrary("YanboberJniLibName");? //defaultConfig.ndk.moduleName
}
好了,到此AS下NDK JNI開發(fā)的代碼編寫和設(shè)置就OK了,接下來就是編譯工程運(yùn)行就可以了。
但是有些電腦好奇怪此時(shí)編譯會(huì)報(bào)錯(cuò),妹的,沒轍,后來網(wǎng)上找到答案說這是NDK在Windows下一個(gè)bug,當(dāng)只編譯一個(gè)單一文件時(shí)出現(xiàn),解決辦法就是再添加一個(gè)空的文件就行了,這個(gè)網(wǎng)站有介紹:NDK在Windows的一個(gè)bug。不過你要是剛才能順利編譯就沒必要蛋疼這個(gè)問題了。
好了,我的編譯運(yùn)行結(jié)果如下:
