先来一张截图
1.TestJni类中声明native的方法,并且需要静态引入我们通过ndk交叉编译后的lib(Android中也就是 .so文件)
- 可以看到我这边写了两个native方法,用来区分静态注册、动态注册native方法
- static静态代码块可以看到和项目的jni目录下生成的so包名字不一样,这里需要省略lib前缀和.so后缀
2.com_csh_test_TestJni.h 这个是头文件,可以自己按照规范写 ,当然不需要自己写,可以通过javah命令生成,首先需要将TestJni这个类javac编译成字节码,然后对这个class文件用javah生成.h文件
3.首先看看test.c(注意是c不是c++,c++有些区别)
当然有点c语言基础的都知道,本人c语言比较烂,多多指教啊
- 首先引入头文件
- 静态注册native方法直接实现就好,按照jni的java与c之间的转换规则
- 动态注册这里只说说怎么做,JNINativeMethod数组可以有多个方法映射,第一第三个参数是映射java中声明的native方法dynamicRegFromJni对应到c中自己定义的方法nativeDynamicRegFromJni,第二个参数()Ljava/lang/String; 其中()是指native方法参数为空,Ljava/lang/String;是指返回值为string (方法描述,数据类型描述 参考)
- JNI_OnLoad(JavaVM *jvm, void *reserved)这个方法是load so文件的时候会被调用,我们就在这个方法中实现动态注册
4.Android.mk文件这里我是手动写的,也可以gradle中配置自动生成(参考)
最后说一句
实践了c++写法略有不同
可以看到区别在指针与引用的区别
查看jni.h中JNIEnv的定义:
#if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
#else
typedef const struct JNINativeInterface* JNIEnv;
#endif
发现C和C++对于JNIEnv定义不同,简单点说,c++是支持类可以直接通过类引用调用方法,c则取出函数指针所引用的值去调用相应的方法