Jobject 对象 引用类型
Java类型 | 本地类型(JNI) | 描述 |
boolean(布尔型) | jboolean | 无符号8个比特 |
byte(字节型) | jbyte | 有符号8个比特 |
char(字符型) | jchar | 无符号16个比特 |
short(短整型) | jshort | 有符号16个比特 |
int(整型) | jint | 有符号32个比特 |
long(长整型) | jlong | 有符号64个比特 |
float(浮点型) | jfloat | 32个比特 |
double(双精度浮点型) | jdouble | 64个比特 |
void(空型) | void | N/A |
函数操作
函数 | Java 数组类型 | 本地类型 | 说明 |
GetBooleanArrayElements | jbooleanArray | jboolean | ReleaseBooleanArrayElements 释放 |
GetByteArrayElements | jbyteArray | jbyte | ReleaseByteArrayElements 释放 |
GetCharArrayElements | jcharArray | jchar | ReleaseShortArrayElements 释放 |
GetShortArrayElements | jshortArray | jshort | ReleaseBooleanArrayElements 释放 |
GetIntArrayElements | jintArray | jint | ReleaseIntArrayElements 释放 |
GetLongArrayElements | jlongArray | jlong | ReleaseLongArrayElements 释放 |
GetFloatArrayElements | jfloatArray | jfloat | ReleaseFloatArrayElements 释放 |
GetDoubleArrayElements | jdoubleArray | jdouble | ReleaseDoubleArrayElements 释放 |
GetObjectArrayElement | 自定义对象 | object | |
SetObjectArrayElement | 自定义对象 | object | |
GetArrayLength | 获取数组大小 | ||
New<Type>Array | 创建一个指定长度的原始数据类型的数组 | ||
GetPrimitiveArrayCritical | 得到指向原始数据类型内容的指针,该方法可能使垃圾回收不能执行,该方法可能返回数组的拷贝,因此必须释放此资源。 | ||
ReleasePrimitiveArrayCritical | 释放指向原始数据类型内容的指针,该方法可能使垃圾回收不能执行,该方法可能返回数组的拷贝,因此必须释放此资源。 | ||
NewStringUTF | jstring类型的方法转换 | ||
GetStringUTFChars | jstring类型的方法转换 | ||
DefineClass | 从原始类数据的缓冲区中加载类 | ||
FindClass | 该函数用于加载本地定义的类。它将搜索由CLASSPATH 环境变量为具有指定名称的类所指定的目录和 zip文件 | ||
GetObjectClass | 通过对象获取这个类。该函数比较简单,唯一注意的是对象不能为NULL,否则获取的class肯定返回也为NULL | ||
GetSuperclass | 获取父类或者说超类 。 如果 clazz 代表类class而非类 object,则该函数返回由 clazz 所指定的类的超类。 如果 clazz指定类 object 或代表某个接口,则该函数返回NULL | ||
IsAssignableFrom | 确定 clazz1 的对象是否可安全地强制转换为clazz2 | ||
Throw | 抛出 java.lang.Throwable 对象 | ||
ThrowNew | 利用指定类的消息(由 message 指定)构造异常对象并抛出该异常 | ||
ExceptionOccurred | 确定是否某个异常正被抛出。在平台相关代码调用 ExceptionClear() 或 Java 代码处理该异常前,异常将始终保持抛出状态 | ||
ExceptionDescribe | 将异常及堆栈的回溯输出到系统错误报告信道(例如 stderr)。该例程可便利调试操作 | ||
ExceptionClear | 清除当前抛出的任何异常。如果当前无异常,则此例程不产生任何效果 | ||
FatalError | 抛出致命错误并且不希望虚拟机进行修复。该函数无返回值 | ||
NewGlobalRef | 创建 obj 参数所引用对象的新全局引用。obj 参数既可以是全局引用,也可以是局部引用。全局引用通过调用DeleteGlobalRef() 来显式撤消。 | ||
DeleteGlobalRef | 删除 globalRef 所指向的全局引用 | ||
DeleteLocalRef | 删除 localRef所指向的局部引用 | ||
AllocObject | 分配新 Java 对象而不调用该对象的任何构造函数。返回该对象的引用。clazz 参数务必不要引用数组类。 | ||
getObjectClass | 返回对象的类 | ||
IsSameObject | 测试两个引用是否引用同一 Java 对象 | ||
NewString | 利用 Unicode 字符数组构造新的 java.lang.String 对象 | ||
GetStringLength | 返回 Java 字符串的长度(Unicode 字符数) | ||
GetStringChars | 返回指向字符串的 Unicode 字符数组的指针。该指针在调用 ReleaseStringchars() 前一直有效 | ||
ReleaseStringChars | 通知虚拟机平台相关代码无需再访问 chars。参数chars 是一个指针,可通过 GetStringChars() 从 string 获得 | ||
NewStringUTF | 利用 UTF-8 字符数组构造新 java.lang.String 对象 | ||
GetStringUTFLength | 以字节为单位返回字符串的 UTF-8 长度 | ||
GetStringUTFChars | 返回指向字符串的 UTF-8 字符数组的指针。该数组在被ReleaseStringUTFChars() 释放前将一直有效 | ||
ReleaseStringUTFChars | 通知虚拟机平台相关代码无需再访问 utf。utf 参数是一个指针,可利用 GetStringUTFChars() 获得 | ||
NewObjectArray | 构造新的数组,它将保存类 elementClass 中的对象。所有元素初始值均设为 initialElement | ||
Set<PrimitiveType>ArrayRegion | 将基本类型数组的某一区域从缓冲区中复制回来的一组函数 | ||
GetFieldID | 返回类的实例(非静态)域的属性 ID。该域由其名称及签名指定。访问器函数的 Get<type>Field 及 Set<type>Field系列使用域 ID 检索对象域。GetFieldID() 不能用于获取数组的长度域。应使用GetArrayLength()。 | ||
Get<type>Field | 该访问器例程系列返回对象的实例(非静态)域的值。要访问的域由通过调用GetFieldID() 而得到的域 ID 指定。 | ||
Set<type>Field | 该访问器例程系列设置对象的实例(非静态)属性的值。要访问的属性由通过调用 SetFieldID() 而得到的属性 ID指定。 | ||
GetStaticFieldID GetStatic<type>Field SetStatic<type>Field | 同上,只不过是静态属性。 | ||
GetMethodID | 返回类或接口实例(非静态)方法的方法 ID。方法可在某个 clazz 的超类中定义,也可从 clazz 继承。该方法由其名称和签名决定。 GetMethodID() 可使未初始化的类初始化。要获得构造函数的方法 ID,应将<init> 作为方法名,同时将void (V) 作为返回类型。 | ||
CallVoidMethod | |||
CallObjectMethod | |||
CallBooleanMethod | |||
CallByteMethod | |||
CallCharMethod | |||
CallShortMethod | |||
CallIntMethod | |||
CallLongMethod | |||
CallFloatMethod | |||
CallDoubleMethod | |||
GetStaticMethodID | 调用静态方法 | ||
Call<type>Method | |||
RegisterNatives | 向 clazz 参数指定的类注册本地方法。methods 参数将指定 JNINativeMethod 结构的数组,其中包含本地方法的名称、签名和函数指针。nMethods 参数将指定数组中的本地方法数。 | ||
UnregisterNatives | 取消注册类的本地方法。类将返回到链接或注册了本地方法函数前的状态。该函数不应在常规平台相关代码中使用。相反,它可以为某些程序提供一种重新加载和重新链接本地库的途径。 | ||
域描述符
域 | Java 语言 |
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
引用类型则为 L + 该类型类描述符 + 。
数组,其为 : [ + 其类型的域描述符 + 。
多维数组则是 n个[ +该类型的域描述符 , N代表的是几维数组。
- String类型的域描述符为 Ljava/lang/String;
- [ + 其类型的域描述符 + ;
- int[ ] 其描述符为[I
- float[ ] 其描述符为[F
- String[ ] 其描述符为[Ljava/lang/String;
- Object[ ]类型的域描述符为[Ljava/lang/Object;
- int [ ][ ] 其描述符为[[I
- float[ ][ ] 其描述符为[[F
JNIEnv与JavaVM
JNIEnv 概念 : 是一个线程相关的结构体, 该结构体代表了 Java 在本线程的运行环境 ;
JNIEnv 与 JavaVM : 注意区分这两个概念;
-- JavaVM : JavaVM 是 Java虚拟机在 JNI 层的代表, JNI 全局只有一个;
-- JNIEnv : JavaVM 在线程中的代表, 每个线程都有一个, JNI 中可能有很多个 JNIEnv;
JNIEnv 作用 :
-- 调用 Java 函数 : JNIEnv 代表 Java 运行环境, 可以使用 JNIEnv 调用 Java 中的代码;
-- 操作 Java 对象 : Java 对象传入 JNI 层就是 Jobject 对象, 需要使用 JNIEnv 来操作这个 Java 对象;
JNIEnv 体系结构
线程相关 : JNIEnv 是线程相关的, 即 在 每个线程中 都有一个 JNIEnv 指针, 每个JNIEnv 都是线程专有的, 其它线程不能使用本线程中的 JNIEnv, 线程 A 不能调用 线程 B 的 JNIEnv;
JNIEnv 不能跨线程 :
-- 当前线程有效 : JNIEnv 只在当前线程有效, JNIEnv 不能在 线程之间进行传递, 在同一个线程中, 多次调用 JNI层方法, 传入的 JNIEnv 是相同的;
-- 本地方法匹配多JNIEnv : 在 Java 层定义的本地方法, 可以在不同的线程调用, 因此 可以接受不同的 JNIEnv;
JNIEnv 结构 : 由上面的代码可以得出, JNIEnv 是一个指针, 指向一个线程相关的结构, 线程相关结构指向 JNI 函数指针 数组, 这个数组中存放了大量的 JNI 函数指针, 这些指针指向了具体的 JNI 函数;
注意:JNIEnv只在当前线程中有效。本地方法不能将JNIEnv从一个线程传递到另一个线程中。相同的 Java 线程中对本地方法多次调用时,传递给该本地方法的JNIEnv是相同的。但是,一个本地方法可被不同的 Java 线程所调用,因此可以接受不同的 JNIEnv。