JNI方法根据定义和用途分为4类。
- 虚拟机安装启用一系列原生方法。这些方法是调用接口的一部分。这些方法可以用来完成一些任务(比如在原生应用中创建虚拟机实例)。
- JavaVM接口代表一个虚拟机实例。JavaVM接口提供了一些方法(比如允许本地线程添加到虚拟机)。
- 继承了原生方法的的原生library可能会输出一些特殊的工具方法(这些方法将会被调用,当虚拟机加载或者卸载原生library的时候)
- JNIEnv 接口支持JNI的一些属性。
直接调用函数
JNI_GetDefaultJavaVMInitArgs
JNI_CreateJavaVM
JNI_GetCreatedJavaVms
JNI_GetDefaultJavaVMInitArgs:获取创建虚拟机默认的初始化参数值。这个方法主要用于jdk1.1,在java2 skd1.2已经不推荐使用,但是仍然向后兼容此方法。
JNI_CreateJavaVM:根据初始化参数创建虚拟机实例。在jdk1.1中通过设置c结构体中的字段值来初始化参数。在java2 sdk1.2中,支持多种方法来初始化参数值,也仍然兼容jdk1.1的方式。
JNI_GetCreatedJavaVMs:获取当前进程中所有的虚拟机实例。某些特殊的JNI实现在同一进程中不能创建多个虚拟机实例。在jdk1.1和java2 sdk1.2中也不支持同一进程中创建多个虚拟机实例。
嵌入了虚拟机实例的本地应用可以调用这些方法。本地应用既可以直接链接虚拟机的函数库,也可以在运行期间动态的装载函数库,查找所有的输出函数。
JavaVM接口
JavaVM是一个指向函数表的指针。函数表中的前三个函数被保留用于以后的兼容。剩下的4个函数如下:
DestroyJavaVM
AttachCurrentThread
DetachCurrentThread
GetEnv
不像JNIEnv接口指针只针对特定的线程,JavaVM代表完整的虚拟机实例并且在同一个虚拟机的多个线程中仍然合法。
DestroyJavaVM函数用来卸载JavaVM表示的虚拟机实例。
AttachCurrentThread函数将当前线程附加到虚拟机上。它能够获取JNI的函数调用并执行类获取objects和一些方法的调用。
DetachCurrentThread函数通过通知当前线程的虚拟机当不需要调用函数时,清空释放资源。
GetEnv是java 2 sdk1.2中的新函数。它有两个功能。首先,可以用来判断当前的虚拟机实例是否已添加。另一方面,它能够获取一些其他的接口,比如通过JavaVM的接口指针获取JniEnv的接口。
本地库中定义的函数
Java2 SKD1.2版本允许程序输出一些附加的功能函数当虚拟机加载或卸载本地函数库时。当虚拟机加载了本地的函数库,它将搜索并且调用输出函数:JNI_OnLoad。当虚拟机卸载本地函数库时,它将会搜索并且调用输出函数: JNI_OnUnload。
JNIEnv接口
JNIEnv接口支持JNI的核心函数。虚拟机启动时会为本地方法传递一个JNIEnv接口指针。本地代码也可以通过调用GetEnv函数来获取JNIEnv接口指针。JNIEnv在个别线程中有效,但是JavaVM在虚拟机的所有线程中都合法。
JNIEnv是函数表的一个指针。函数表中前三个被保留用来兼容。第四个函数也被保留将来使用并置为NULL。
下面将大概的介绍一些JniEnv的接口。
版本信息
GetVersion返回JNIEnv接口的版本信息。
类和接口操作
DefineClass通过字节数组表示原始的类文件数据,来定义一个类或接口的类型。
FindClass返回给定名字的类或接口的引用
GetSuperclass返回给定类或接口的superclass
IsAssignableFrom用来检查一个类或接口能不能指定给另一个类或接口,和检查运行时的类型是否有用。
Exceptions
Throw和ThrowNew在当前线程抛出一个异常。
ExceptionOccurred和ExceptionCheck检查当前线程中未处理的异常
ExceptionCheck是java2 sdk1.2中的新函数。
ExceptionClear清除未处理的异常
FatalError打印错误信息并终止当前虚拟机。
全局引用和局部引用
NewGlobalRef创建一个全局引用。DeleteGlobalRef删除一个全局引用。
NewWeakGlobalRef和DeleteWeakGlobalRef管理全局虚引用。(这两个函数都是java2 sdk1.2中才有)
DeleteLocalRef回收利用虚拟机资源给局部引用
NewLocalRef创建局部引用(java2 sdk1.2才有)
EnsureLocalCapacity在当前线程存储固定的空间供局部引用创建时使用。(java2 sdk1.2)
PushLocalFrame和PopLocalFrame为本地应用创建一个嵌套域。(Java2 sdk1.2)
对象操作函数
AllocObject分配一个未初始的object
NewObject分配一个object并且运行其构造函数
GetObjectClass返回指定实例的class
IsInstanceOf判断给定的object是否属于指定类或接口
IsSameObject判断两个引用是否指向同一个object
获取实例的FieldID
GetFieldID通过查找给定类接口的特征并且返回被命名的实例字段的fieldID
Get< Type>Field和Set< Type>Field来获取设置实例字段。
获取静态实例的FieldID
GetStaticFieldID通过查找给定类接口的特征,并且返回被命名的静态实例字段的fieldID
GetStatic< Type>Field和SetStatic< Type>获取设置静态实例字段。
实例方法调用
GetMethodID通过给定类接口的特征来查找并返回实例方法或构造方法的ID
Call< Type>Method调用实例方法
CallNonvirtual< Type>Method调用实例方法的父类或构造方法
调用静态方法
GetStaticMethodID通过给定类的特征来查找并返回静态方法的ID
CallStatic< type>Method:调用静态方法。
String操作函数
NewString创建一个java.lang.String对象来表示Unicode字符串。
NewStringUTF创建一个java.lang.String对象来表示UTF-8字符串。
GetStringLength返回Unicode字符串长度
GetStringLengthUTF返回UTF-8字符串长度
GetStringChars和ReleaseStringChars操作java.lang.String对象作为Unicode字符串指针的内容
GetStringUTFChars和ReleaseStringUTFChars操作UTF-8字符串指针。
GetStringCritical和ReleaseStringCritical以最低的消耗来操作字符串。(java 2 sdk1.2)
GetStringGegion和GetStringUTFRegion 复制字符串内容到本地缓冲。(java2 sdk1.2)
数组操作函数
GetArrayLength返回数组元素个数
NewObjectArray创建一个数组对象。
New< Type>Array 创建基本类型数组
GetObjectArrayElement和SetObjectArrayEmement允许本地代码操作引用类型数组
Get< Type>ArrayElements和Release< Type>ArrayElements操作所有的原始数据类型元素。
Get< Type>ArrayRegion和Set< Type>ArrayRegion复制数组中多个元素
GetPrimitiveArrayCritical和ReleasePrimitiveArrayCritical以最小的代价来处理基本数据类型的数组元素。(java 2 sdk1.2)
注册方法
RegisterNatives和UnregisterNatives允许本地代码更早的连接或不连接本地方法。
监听方法
MonitorEnter和MonitorExit将会同步执行,当monitor与对象产生关联。
JavaVM方法
GetJavaVM返回当前虚拟机的JavaVM接口指针
反射
FromReflectedField把实例在java的核心反射API中java.lang.reflect.Field转换成field IDs。(java 2 sdk1.2)
FromReflectedMethod把java中的实例方法或构造方法的反射转换成方法IDs。(java 2 sdk 1.2)
ToReflectedField和ToReflectedMethod执行相反的转换。(java 2 skd 1.2)