Android JNI中C和JAVA代碼之間的互相調用

1.com.devicetest

com.devicetest.ndkmac

新建com.devicetest.ndkmac.JNITest.java

2.打開android studio終端,使用javac編譯上述文件,生成class文件。

切換到app/src/main/java/com/devicetest/ndkmac目錄下執行javac JNITest.java

AndroidStudioProject/DeviceTest/app/src/main/java/com/devicetest/ndkmac$ javac JNITest.java


生成JNITest.class的文件


3.javah 生成jni樣式的標準頭文件

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

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

切換到app/src/main/java目錄下執行javah -jni com.devicetest.ndkmac.JNITest

AndroidStudioProject/DeviceTest/app/src/main/java$ javah -jni com.devicetest.ndkmac.JNITest

然後就能看到生成了一個h文件。
4、新建一個jni文件夾,新建main.c,把.h裏面的內容複製進去,並實現裏面的函數。


生成的h文件

拷貝修改後的main.c

完成頭文件中的變量(JNIEnv *env, jobject obj):
JNIEXPORT jstring JNICALL Java_com_devicetest_ndkmac_JNITest_helloJniFromC
  (JNIEnv *env, jobject obj)
  {
      return (*env)->NewStringUTF(env,"I am Str from jni libs 2019-10-22!");
  }

 

還要在jni文件夾下添加一個空白的util.c文件,不然會報錯,我也不知道爲什麼。

5、配置NDK

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

ndk.dir=/home/produce/Android/Sdk/ndk-bundle
sdk.dir=/home/produce/Android/Sdk


6.

在defaultConfig下面添加

externalNativeBuild {
            cmake {
                abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' // 定義編譯的ABI類型,每種會編譯生成一個對應的so庫文件
            }
        }

 

在android下面添加

    externalNativeBuild {
        cmake {
            path 'src/main/java/com/devicetest/jni/CMakeLists.txt'
        }
    }

 

src/main/java/com/devicetest/jni/CMakeLists.txt的內容如下:

cmake_minimum_required(VERSION 3.10.2)

add_library( # Specifies the name of the library.
             native-vendorstorage-lib
             # Sets the library as a shared library.
             SHARED
             # Provides a relative path to your source file(s).
             com_devicetest_ndkmac_MacTools.c )

 


7.還要在gradle.properties裏面加上這麼一句話:

android.useDeprecatedNdk=true

8.生成SO庫

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

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

 

9.配置so庫

在src\main下新建文件夾jniLIB,並將生成的SO文件拷貝到該文件夾下

Android NDK開發之從Java與C互調中詳解JNI使用(一)
https://www.cnblogs.com/guanmanman/archive/2017/05/05/6811264.html

 

10、使用JNI

因爲native方法聲明成了靜態的方法,在Activity裏面直接調用myJNI類就行

text = (TextView)findViewById(R.id.text);
//調用
text.setText(myJNI.sayHello())

11.執行build->Make Project


生成so文件

app/build/intermediates/cmake/debug/obj/arm64-v8a
app/build/intermediates/cmake/debug/obj/armeabi-v7a
app/build/intermediates/cmake/debug/obj/x86
app/build/intermediates/cmake/debug/obj/x86_64

總結一下流程:

編寫靜態方法(用java聲明)-->編譯生成class文件--->編譯生成h文件---->編寫C文件(用C/C++實現)

---->配置NDK---->配置so庫---->在Activity調用(Java調用C/C++)。

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