NDK-JNI實戰教程(一) 在Android Studio運行第一個NDK程序

jopen 8年前發布 | 38K 次閱讀 Android開發 移動開發

PS一句:最終還是選擇CSDN來整理發表這幾年的知識點,該文章平行遷移到CSDN。因為CSDN也支持MarkDown語法了,牛逼啊!

NDK開發,其實是為了項目需要調用底層的一些C/C++的一些東西;另外就是為了效率更加高些。如果你在Eclipse+ADT下開發過NDK就能體會到要么是配置NDK還要下載Cygwin,配置Cygwin ,然后需要編譯生成,相當的蛋疼。要么是直接用Eclipse開發,但是前期配置也是一堆;真心蛋疼。但是現在在AS上Eclipse能做到的這邊都OK,這邊有的Eclipse上沒有的,而且Google親生的支持下只會越來越比Eclipse下開發NDK更加牛逼,所以你還不準備上手嗎?

在AS開發NDK JNI也需要配置,不過相當Easy。第一步就是去官方下載個NDK包就可以了,像我的直接放在D盤就行了。關于怎么下載安裝看這里 AD NDK會有介紹。

第二步就是就是直接寫代碼了。哈哈,你沒聽錯,是這樣的,方便吧?至于下載下來的NDK怎么和AS工程關聯,也就是一行配置的問題,后文有說明帶你一步一步體驗。

But,還是要有個but,Android Studio還不是個壯年,尤其在NDK開發中,所以本文只是工具性的演示,實質是教會大家NDK開發。

Let’s Go!!!

在AS中新建一個Project,然后再新建一個class為NdkJniUtils,在內部聲明native方法(jni使用的定義,后面系列教程會細說)。

package io.github.yanbober.ndkapplication;

public class NdkJniUtils {
    public native String getCLanguageString();
}

在工程主文件Activity中寫入如下代碼調運JNI的東西顯示在UI上。

public class MainActivity extends ActionBarActivity {
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextView = (TextView) this.findViewById(R.id.test);

        NdkJniUtils jni = new NdkJniUtils();

        mTextView.setText(jni.getCLanguageString());
    }
}

然后build project得到其中中間文件,我們關注的是.class文件。編譯OK以后生成的class文件在AS工程的如下目錄:

NDKApplication\app\build\intermediates\classes\debug

然后接下來的步驟就是根據生成的class文件,利用javah生成對應的 .h頭文件。

點開AS的Terminal標簽,默認進入到該項目的app文件夾下。我在windows平臺下輸入如下命令跳轉到class中間文件生成路徑:

xxxxx\app> cd build\intermediates\classes\debug

然后執行如下javah命令生成h文件。

xxxxx\debug> javah -jni io.github.yanbober.ndkapplication.NdkJniUtils

執行完之后你可以在文件夾NDKApplication\app\build\intermediates\classes\debug下看見生成的 .h頭文件為:

io_github_yanbober_ndkapplication_NdkJniUtils.h

其內容為:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* 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 "C" {
#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目錄下新建一個名字為jni的目錄,然后將剛才的 .h文件剪切過來。在jni目錄下新建一個c文件,隨意取名,我的叫jnitest.c 。然后編輯代碼如下(后面會解釋啥意思,這里重在工具使用):

#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 obj){
     return (*env)->NewStringUTF(env,"This just a test for Android Studio NDK JNI developer!");
  }

接下來在工程的local.properties文件中添加NDK路徑(上面下載好的那個NDK),類似其中的SDK路徑一樣,我的添加后如下:

sdk.dir=D\:\\AndroidStdioSDK\\sdk
#add by 工匠若水
ndk.dir=D\:\\AndroidStdioSDK\\android-ndk-r10d-64bit

接下來在app module目錄下的build.gradle中設置庫文件名(生成的so文件名)。找到gradle文件的defaultConfig這項,在里面添加如下內容:

defaultConfig {
    ......
    ndk{
        moduleName "YanboberJniLibName"         //生成的so名字
        abiFilters "armeabi", "armeabi-v7a", "x86"  //輸出指定三種abi體系結構下的so庫。目前可有可無。
    }
}

現在生成的so庫名字也有了,那就去代碼的NdkJniUtils java文件添加靜態初始化load代碼,添加如下:

static {
        System.loadLibrary("YanboberJniLibName");   //defaultConfig.ndk.moduleName
    }

好了,到此AS下NDK JNI開發的代碼編寫和設置就OK了,接下來就是編譯工程運行就可以了。

但是有些電腦好奇怪此時編譯會報錯,妹的,沒轍,后來網上找到答案說這是NDK在Windows下一個bug,當只編譯一個單一文件時出現,解決辦法就是再添加一個空的文件就行了,這個網站有介紹:NDK在Windows的一個bug。不過你要是剛才能順利編譯就沒必要蛋疼這個問題了。

好了,我的編譯運行結果如下:

這里寫圖片描述

到此為止簡單的體驗AS下NDK開發的過程就結束了。期待下一篇再續深入。

【工匠若水 http://blog.csdn.net/yanbober】 繼續閱讀《 NDK-JNI實戰教程(二) JNI官方中文資料》 http://blog.csdn.net/yanbober/article/details/45310365

這里寫圖片描述

來自: http://blog.csdn.net//yanbober/article/details/45309049

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!