Android框架基础JNI

JNI(Java Native Interface ,Java本地接口)是Java平台上定义的一套标准的本地编程接口。JNI 允许Java代码与本地代码互操作,也就是说Java代码可以调用本地代码本地代码也可以调用Java 代码。所谓本地代码指的是用其他编程语言(如C/C++)实现的、依赖于特定硬件和操作系统的代码。通过JNI 调用本地代码,可以实现Java语言所不能实现的功能。在Android 平台上,Dalvik 虚拟机会实现JNI定义的接口。JNI 框架层大量使用了JNI 技术来完成对系统运行库的调用。

JNI 编程分为以下三个步骤:

  1. Java层声明Native 方法。
  2. JNI层实现Java层声明的Native 方法,在JNI层 可以调用底层库或者回调Java层方法。这部分将被编译为动态库(so文件)工系统加载。
  3. 加载JNI 层代码代码编译后生成的共享库。

使用JNI 有两种方式:

  1. 遵守JNI 规范的函数命名规范,建立声明函数和实现函数之间的对应关系。
  2. 采用函数注册方式。

在使用JNI 编程时会遇到 JNIEnv 这个指针,它相当于是JNI “总管”,通过它调用JNI  函数,访问Java虚拟机,进而操作Java对象。

JNIEnv 只在当前线程中有效。本地方法不能将JNIEnv 从一个线程传递到另一个线程中。相同的Java 线程中对本地方法多次调用时,传递给该本地方法的JNIEnv 是相同的。但是,一个本地方法可被不同的Java线程所调用,因此可以接受不同的JNIEnv。

JNI实现方法的命名规则:

  1. Java_   前缀
  2. 权限定的类名
  3. 下划线 (_)分隔符
  4. 增加第一个参数 JNIEnv * env
  5. 增加第二个参数 jobject
  6. 其他参数按类型映射
  7. 返回值按类型映射

第一个参数前面已经介绍过。第二个参数因本地方法是静态还是非静态而有所不同。非静态本地方法的第二个参数是对Java 对象的引用,而静态本地方法的第二个参数是对其Java 类的引用。其余参数对应Java方法的参数。

JNI 方法签名规则:

JNI方法签名规则如下:

(参数1类型签名参数2类型签名........参数n类型签名)返回值类型签名

注意:以上签名字符串之间均没有空格。


JNI 是如何操作Java对象的呢?

JNI 方法接受的第二个参数是Java对象:jobject,可以在JNI 中操作这个jobject 进而操作Java对象提供的变量和方法。

全局引用、若全局引用和局部引用

Java 对象的生命周期有虚拟机管理,虚拟机内部维护一个对象的引用计数,如果一个对象的引用计数为0,那么这个对象将被垃圾回收器回收并释放内存。

  1. 局部引用:
    可以增加引用计数,作用范围为本线程,生命周期为一次Native 调用,即:只在Native 方法的一次调用中有效,在该方法返回后,被虚拟机回收。
  2. 全局引用:
    可以增加引用计数,作用范围为多线程,生命周期到显式释放。全局引用通过JNI 函数NewGlobalRef 创建,并通过DeleteGlobalRef 释放。注意:如果程序员不显式释放,将永远不会被垃圾回收。
  3. 弱全局引用:
    不能增加引用计数。作用范围为多线程,多个Native 方法,生命周期到显式释放。弱全局引用通过JNI 函数NewWeakGlobalRef 创建,并通过DeleteWeakGlobalRef 释放。弱全局引用的优点是既可以保存对象,又不会阻止该对象被回收。注意:使用弱全局引用的 时候,它所指向的对象可能已经被回收了。JNI 提供了IsSameObject 函数用来判断弱引用对应的对象是否已经被回收,方法是用弱全局引用和NULL 进行比较。如果返回JNI_TRUE ,则说明弱全局引用指向的 对象已经被回收了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值