必要环境: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