必要環境:NDK ,我的版本是android-ndk-r10
最後結果如圖:
實現過程:
1.新建一個as工程,再新建一個類,聲明native方法,此方法是調用c/c++的,是java層和c/c++的中介
public class JNIMethod { static { System.loadLibrary("HelloJNI"); } public static native String sayHello(); }
2.在該類的目錄下,使用javac命令將java文件編譯成class文件:javac xx.java
3.在包名的上一級目錄,使用javah將class文件編譯成 .h文件:javah -jni com.example.xx,如:我的包名是
package me.com.jnihello
那就在me的上一級目錄編譯
4.在main目錄下(和java文件夾同級),新建一個文件夾jni,在jni文件夾下新建c文件JNIMain.c,將.h文件的內容複製進去,並實現其中的函數。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class me_com_jnihello_JNIMethod */ #ifndef _Included_me_com_jnihello_JNIMethod #define _Included_me_com_jnihello_JNIMethod #ifdef __cplusplus extern "C" { #endif /* * Class: me_com_jnihello_JNIMethod * Method: sayHello * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_me_com_jnihello_JNIMethod_sayHello (JNIEnv *env, jclass jobj){ return (*env)->NewStringUTF(env,"this is jni,hello world!"); } #ifdef __cplusplus } #endif #endif
還需要在jni文件夾下新建一個空白的文件 util.c ,不建的話會報錯。原因自行探尋...
5.配置NDK,在工程的local.properties加入ndk路徑
ndk.dir=E\:\\android-ndk-r10
在module的build.gradle文件裏,default config節點下加入配置
defaultConfig { applicationId "me.com.jnihello" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk{ moduleName "HelloJNI" ldLibs "log","z","m" abiFilters "armeabi","armeabi-v7a","x86" } }moduleName需要和java類裏面加載的庫名相同。abifilters 裏面的類型代表編譯出哪幾種類型的so
還需要在gradle.properties裏面加入
android.useDeprecatedNdk = true
6. rebuild project 就可以生成so庫
7.配置so庫,有兩種方法:
1.在main目錄下新建jniLibs文件夾,將第6步獲得的so庫放進去,在build.gradle加入下面這句
sourceSets.main { jni.srcDirs = [] jniLibs.srcDir 'src/main/jniLibs' }新建的文件夾其實可以起別的名字,只要和build.gradle裏面能對應就可以
2.將so文件放到app目錄下的libs文件夾下
8.調用jni,直接使用jni類中的靜態方法
TextView textView = ((TextView) findViewById(R.id.hello)); textView.setText(JNIMethod.sayHello());
項目上傳github: https://github.com/a1510312433/jni2so