一、如何生成.so库
首先在SDKmanager中下载NDK 相关工具
配置DNK
找到SDK中的ndk-bundel 配置好路径(上一步安装自动就会帮你配置,我是 studio 2.3)
配置完成。
创建一个调用C代码中的方法的类
在APP的build.gradle中添加ndk{
moduleName "native-jni"
abiFilters "armeabi-v7a","x86"
}
moduleName 是最后生成的.so库的名字(最后的.so名字是libnative-jni,前面会加一个lib)在上面System.loadLibrary("native-jni");中so库名前面是没有lib的。
abiFilters 是要生成的CPU框架的.so库,我在配置这个时候 “armeabi”, "armeabi-v7a","x86",但是总是报armeabi错误,具体错误日志忘记了,意思就是和“armeabi-v7a”关联了,不能用armeabi,我就选择不生成“armeabi”的so库了,
将这个JNIUtils.class rebuild一下得到编译后的class文件
打开Terminal生成.h文件
,首先指定到main路径下
G:\TestJNI>cd G:\TestJNI\app\src\main 我的main路径是G:\TestJNI\app\src\main
然后输入javah -d jni -classpath G:\TestJNI\app\build\intermediates\classes\debug kade.testjni.JNIUtils
这个是javah -d jni -classpath(注意这儿有个空格) +项目app的路径+\build\intermediates\classes\debug(注意这儿有个空格) +包名.JNIUtils,如果点击回车之后如下,回到main,那么在main下面会自动生成一个jni文件,jni文件下会生成一个kade_testjni_JNIUtils.h文件。
图中的native-lib.c 和 a.c请忽略,是后面的步骤,只看生成了kade_testjni_JNIUtils.h文件
在写一个C文件 native-lib.c ,这个C文件就是我们想要实现的通过jni调用的C代码了(a.c文件是一个空的.c文件,很多人说在windows环境下会出问题,好像是NDK的一个bug,一个.c文件就会有这个bug,所以多创建一个空的C文件就OK)
#include"kade_testjni_JNIUtils.h"
JNIEXPORT jstring JNICALL Java_kade_testjni_JNIUtils_stringFromJNI
(JNIEnv*env, jobject jobject1){
return (*env)->NewStringUTF(env,"Hello world !!!");
}
这个include 引入的刚刚自动生成的jni下的kade_testjni_JNIUtils.h文件
方法名请注意写法,JNIEXPORT jstring JNICALL Java_+kade_testjni_JNIUtils(这个是JNIUtils的路径,我的包名是kade.testjni)+_stringFromJNI(这个是JNIUtils类下那个native 方法的方法名)
再次rebuild一下就能生成.so文件了,(这里这个)
so库位置
在src下创建jniLibs文件 并将so库copy过来(我这儿有个armeabi其实也是我把armeabi-v7a中的so copy过来的,其实只要留一个armeabi就可以了,或者一个armeabi-v7a)
最后在刚刚这个项目中调用一下这个,看成功没有
如果so生成了,但是调用的时候报错,而且是
这个一直报错
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__register_atfork" referenced by "libjni.so"...
网上说修改Android.mk文件,或者说NDK版本要R13还是R14才行,我弄了半天,我更本没用Android.mk文件呀,改NDK,我想我是NDK17.1,高版本应该没问题吧。弄了半天,最后我在我手机上运行通过了,发现在我这个系统是7.1的安卓手机上可以调通,但是我这个定制的4.4的安卓设备不行,百度未果,后面我相信是版本的问题,在app 的build.gradle中我的编译版本设置成compileSdkVersion 25,targetSdkVersion 25,将这个版本修改成22后,在次运行,运行后将build中的intermediates下的ndk中的重新生成的so库放到jinLibs中替换,问题得到解决。