NDK-JNI實(shí)戰(zhàn)教程 在Android Studio運(yùn)行第一個(gè)NDK程序

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é)果如下:


最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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