第2章 深入理解JNI

1.JNI层连同了Java世界和Native世界
2.Java<-->JNI<-->Native
  exp:MediaScanner<-->libmedia_jni.so<-->libmedia.so
  库名没有规定的命名规则
  JNI层必须实现为动态库的形式,这样java虚拟机才能加载并调用它的函数。

3.Java层
  1)加载JNI库
    通用的做法是在类的static语句中加载,调用System.loadLibrary("libname")方法
  2)用native关键字来修饰由JNI层实现的函数

4.JNI层
  1)注册JNI函数
     a)静态方法
       1.编写java代码,编译生成.class文件
       2.使用javah 生成需要实现的头文件
       3.javah -o output.h *.class
       当java层调用native函数时,它会从对应的JNI库中寻找符合规则的函数名。如
        果找到,则会将这个jave层的native函数与Native层的函数关联,其实就是保
        存ntive层函数的指针。以后再使用java层的native函数时,直接使用保存的指
        针即可。这项工作具体是由虚拟机完成的。
*JNI层的函数名字必须遵循固定的格式。
    b)动态注册
       1.Java native函数和JNI函数时一一对应的,由JNINativeMethod结构保存。
       2.调用JNIEnv.RegisterNatives完成注册
       3.当java层通过System.loadLibrary加载完JNI动态库后,紧接着会查找该库中一个叫JNI_OnLoad的函数。如果有,就调用它,而动态注册的工作就是在这里完成的,同时还可以做一些初始化的工作。
  2)JNIEnv
      1.JNIEnv是一个与线程相关的代表JNI环境的结构体。它提供了一些JNI系统函数。它内部保存JNI函数指针数组。
       2.通过JavaVM的AttachCurrentThread函数得到线程的JNIEnv
      3.通过JavaVM的DetachCurrentThread函数来释放对应的资源。
    d) JNI层通过JNIEnv获取jobject
      1.用JNIEnv.GetFieldId获取类成员属性
       2.用JNIEnv.GetMethodId获取类方法
    e)JNI类型签名介绍
       ****
  3)垃圾回收
      Local reference:一旦JNI函数返回,其使用的jobject对象都可能被垃圾回收
      Global reference:全局引用,只有主动释放才会被垃圾回收
      Weak Global reference:弱全局引用,运行过程中可能会被垃圾回收,使用时
      需要用JNIEnv.IsSameObject判断。
     
       JNI层想要保存Java层中的某个对象时,可以使用Global reference.使用完后记得释放。对于Local reference,也需要在合适的时候进行回收,以免java虚拟机内不足。

 
 

猜你喜欢

转载自u010837360.iteye.com/blog/2050051
今日推荐