1、JNI_OnLoad()实现Native函数注册;
2、JAVA端实现动态库加载System.loadLibrary();
3、JAVA定义Native方法;
JAVA实例方法调用:
JNI Native方法通过第二个参数获取JAVA类引用;第二个参数是JAVA对象的引用(本地)。
JAVA静态方法调用:
JNI Native方法通过类名获取JAVA类引用,或者直接使用第二个参数,第二个参数是JAVA类的引用(本地)。
方法Native描述符
javap -s -p InstanceMethodCall,利用工具生成方法的Native描述符,其中InstanceMethodCall是JAVA类名
调用JAVA构造方法:GetMethodID的第二个参数固定为"<init>"字符,就可以获取到JAVA类的构造函数
JNI都是通过不透明引用持有JAVA对象。
一般有三类引用:本地、全局和弱全局;本地引用会自动释放,全局和弱全局需要程序员自己释放;本地和全局引用不会被GC,弱全局会被GC;在创建本地引用的Native方法返回后,继续使用该本地引用是非法的。
本地引用:
大部分JNI内置函数返回的对象是本地引用,调用DeleteLocalRef显示的释放本地引用,主要是为了立即垃圾回收,否则需要等到创建本地引用的整个Native方法执行周期结束并返回JAVA环境才进行垃圾回收
JAVA调用Native方法时传递的对象参数都是本地引用,在Native执行周期内如果JAVA对象被垃圾回收,该本地引用在整个Native执行周期内仍旧有效。
本地引用仅仅在创建它的线程内有效
尽量少创建本地引用,否则可能出现内存耗尽的可能(一般不超过16个),如果必须创建多个本地引用,当不在使用以前创建的本地引用,可以显示的释放本地引用。
全局引用:
可以跨线程使用或跨Native调用使用;NewGlobalRef创建一个全局引用;可以通过本地引用创建全局引用。
弱全局引用:
与全局引用基本一致,但引用关联的对象可以进行垃圾回收。如果关联的对象已经被垃圾回收,可以通过IsSameObject跟NULL对象进行比较,如果返回JNI_TRUE代表对象已经被回收。
jfieldID和jmethodID不是引用,它们的生命周期被JAVA虚拟机管理,它们一直有效直到JAVA虚拟机卸载它们所在类或接口,有效期内可跨线程使用。
另外,Native是基类的实现,需要固定访问基类成员时,就需要缓存它们。