android的JNI學習筆記

1、百度,找到最簡單的學習資料,要類似hello world這樣的,否則事倍功半,切記!!!

2、還真找到了hello, ^_^

3、

新建一個類,聲明native方法。這個類是java與C/C++交互的中介,方法由java聲明,由C/C++實現。

不在Activity類裏面寫是爲了避免編譯時報錯:找不到android.support.v7.app.AppCompatActivity

public class myJNI {

  //加載so庫
    static {
        System.loadLibrary("JniTest");
    }

  //native方法
    public static native String sayHello();

}

4、上一步基本不會有錯,且看這一步:打開android studio終端,使用javac編譯上述文件,生成class文件。

命令:

D:\AndroidStudioProject\testJNI\app\src\main\java\com\example\binbin\testjni>javac myJNI.java

注:這一步就有兩問題,首先,要用CD命令(跟DOS命令一個意思)進入到前面所建的類的那個目錄。

其次 很容易出現  錯誤: 編碼GBK的不可映射字符,這時就要對javac 命令加參數,變成如下:

javac -encoding UTF-8 myJNI.java

OK,這下不報錯了,通過,你會發現那目錄下多了一個myJNI.class的文件

5、確認自己類的包名!然後在上一級的位置使用javah生成.h頭文件

一定要在上一級哦,不然不會報錯:找不到xxx類

這裏一定要注意,要用CD..  命令往回走到包的起始目錄,比如我這裏就要回到D:\AndroidStudioProject\testJNI\app\src\main\java  目錄下,然後執行javah 命令,包名是放在參數中了

D:\AndroidStudioProject\testJNI\app\src\main\java>javah -jni com.example.binbin.testjni.myJNI

OK,現在在java目錄下生成了一個   .h 文件,文件名有點長。

第4步是javac, 第5步是javah

6、在java目錄下新建目錄:jni, 在這新目錄下新建main.c文件,同時把上一步生成的.h文件中的內容複製到此文件中

注:這裏新建的時候,不要建成c/c++ class, 而是要選c/c++ source file ,開始沒留意,死也建不成功。

原.h文件內容:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_binbin_testjni_myJNI */

#ifndef _Included_com_example_binbin_testjni_myJNI
#define _Included_com_example_binbin_testjni_myJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_binbin_testjni_myJNI
 * Method:    sayHello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_binbin_testjni_myJNI_sayHello
        (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

複製,並修改後的main.c中的代碼,就增加了一行 return :

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_binbin_testjni_myJNI */

#ifndef _Included_com_example_binbin_testjni_myJNI
#define _Included_com_example_binbin_testjni_myJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_binbin_testjni_myJNI
 * Method:    sayHello
 * Signature: ()Ljava/lang/String;
 */

//就實現了個函數 JNIEnv的用法可以自行百度,這裏就不展開了
JNIEXPORT jstring JNICALL Java_com_example_binbin_testjni_myJNI_sayHello
        (JNIEnv *env, jclass jobj){

  //返回一句話
    return (*env)->NewStringUTF(env,"JNI hahahahahahahaha");

}

#ifdef __cplusplus
}
#endif
#endif

7、據說還要jni目錄下增加一個util.c的文件,否則會報錯,暫不管,等看到報錯再說,否則都不知有什麼錯,不利於學習^_^

8、配置NDK

打開Project的local.properties文件添加NDK路徑

到了這裏才發現沒有NDK,不要緊,按下面的鏈接,兩三分鐘就下好了,現在對谷歌的下載界面已經沒有屏蔽了,要是幾年前,光下這個,估計就不知要到什麼時候去了,當然那裏網速也慢。^_^

https://dl.google.com/android/repository/android-ndk-r19c-windows-x86_64.zip

 

打開app Module的build.gradle文件,在defaultConfig節點裏添加以下代碼
注意這裏的moduleName,是我們在之前自己編寫的類裏面加載的so庫名
ndk {
            moduleName "JniTest"
            ldLibs "log", "z", "m"
            abiFilters "armeabi", "armeabi-v7a", "x86"
        }

這裏有個坑的地方是,build.gradle文件不要找錯一個了,否則沒地方加這一小段,

另外 abiFilters "armeabi", "armeabi-v7a", "x86" 這個好象是指要匹配的CPU類型??

還要在gradle.properties裏面加上這麼一句話:android.useDeprecatedNdk=true

配置完成

9、生成SO庫

完成以上步驟之後,我們rebuild一下就可以生成so庫了

在項目的app\build\intermediates\ndk\debug\lib路徑下

這一步,死活成功不了,在這intermediates目錄下,找不着ndk目錄,我倒。。。。然後jniLibs下也沒有東西

再百度,發現還需要在build.gradle中增加

sourceSets{
    main{
        jniLibs.srcDir 'src/main/java/jni'//告知jni源碼目錄
    }
}

追加在NDK配置時,那一段NDK的後面即可

但是這到,仍然沒有生成SO文件

已經好晚了,先到這兒,改天繼續研究,暫時判斷的錯誤是前文關於NDK的配置是有問題的,android.useDeprecatedNdk要取消了:

Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章