JNI编程配置
AS支持JNI编写方法有两种,一种是用ndk-bundle,另一种是Cmake,推荐使用Cmake方式进行编写JNI,因为AS本身支持,在编写JNI的时候会有提供语法提示和各种调试,而ndk-bundle则没有,像写文档一样,没有任何的提示,会麻烦很多(可能是AS版本问题)。
还有一个注意点就编写JNI的时候,AS版本最好更新成高版本,否则可能会不支持或者支持程度不太友好。
两者的区别
ndk会自动帮我们实现Android.mk,还有一些配置,开发者只需要设置好ndk的路径和设置使用ndk编译的权限就可以了,无论添加多少个cpp文件都会自动帮你管理并生成好对应so库。
而Cmake方法是AS本身自己提供支持的C++编译的手段,这个感觉更加简单,AS已经提供专门的cpp文件夹供给开发者进行cpp文件创建,需要做的就是当我们创建多个cpp的时候,需要在CmakeList.txt中添加源文件的路径。
一.JNI配置
1.ndk方式配置
①首先创建好native方法,在JNI里面进行方法实现
②在调用的地方加载so库
②在app中的build.gradle中的defaultConfig中进行配置ndk,其中moudleName与第二步中的名字一致,abiFilters则是生成类库的各种CPU平台类型,armeabi,armeabiv7,x86这几种。 但是有一个奇怪的BUG,就是一旦加入另外两种一起生成so库的时候就会报错。
所以只保留armeabi类型
③在gradle.properties中添加android.useDeprecatedNdk=true,相当于开启ndk编译的权限。
④local.properties中设置好NDK的路径(一般而言AS会自动设置好)
2.Cmake方式配置
这种方法基本是不用做什么东西的,除了一个通用的编译步骤,其余的只创建工程,AS已经直接帮你搞定
只需要在创建工程的时候把这个支持C++的功能打钩即可,当然就是要创建好native方法。
3.JNI,两者通用的步骤(必须的)
将包含有的native方法的class进行编译,生成对应的.h文件
首先点击AS Terminal,即是类似cmd的编译窗口,然后进入到java目录,javah acc.gonsin.com.ndkdemo.JniReceiver
确定生成对应的.h文件。
然后新建cpp,把.h文件里面的内容复制到cpp中,并修改参数之类的,然后就可以编写C++
最后Rebuild一下生成so库
NDK生成的so库位置
Cmake生成的so库位置
4.JNI调用(java调用c++方法)
前面的步骤都完成以后,调用就简单了
直接new类对象直接调用即可
二.JNI代码编写规则
除了C++本身的语法以外,jni本身编写也是有规则语法的
JNI的引用关系表(java<——>JNI)
1.c++调用java方法
原理则是通过java的反射还获取到java工程中对应的方法
①首先先通过Findclass获取类
②然后根据方法名来获取menthodID,最后一个参数是方法的类型签名,括号里的就是参数,括号外的表示方法返回类型
比如方法 boolean method(String str , int i) 签名就是(Ljava/lang/String;I)Z
③最后调用方法
调用静态方法(Void类型) env-> CallStaticVoidMethod(类,方法ID,参数1,参数2......)
调用非静态方法(Void类型) env-> CallVoidMethod(类,方法ID,参数1,参数2......)
注意点
C++调用JAVA方法如果忽然闪退,但没有任何报错信息,那么就很可能是调用的时候传参数有错误。
JNI本身还有一些方法,比如常用的jstring类型转char*类型或者char*转jstring
jstring
str = env->NewStringUTF(msgbuf); char*转jstring
const char*
message = (char*)env->GetStringUTFChars(msg,0);
jstring类型转char*