【安卓开发】JNI常用接口 - 4

本文介绍了JNI接口中关于字符串和数组的操作方法,包括创建、获取长度、读取内容等核心功能,并详细解释了各函数的参数及返回值。

9、字符串操作
jstring NewString(JNIEnv *env, const jchar *unicodeChars,jsize len);
根据unicode字符数组构造一个新的java.lang.String对象
参数:
env:JNI接口指针
unicodeChars:指向Unicode字符串的指针
len:unicode字符串的长度
返回:
返回一个java字符串对象,如果该字符串无法被创建,则返回NULL
抛出异常:
OutOfMemoryError:如果系统内存溢出

jsize GetStringLength(JNIEnv *env, jstring string);
返回java字符串的长度(unicode字符的个数)
参数:
env:JNI接口指针
string:java字符串对象
返回:
返回java字符串的长度

const jchar * GetStringChars(JNIEnv *env, jstring string,jboolean *isCopy);
返回指向字符串的UNICODE字符数组的指针,该指针一直有效直到ReleaseStringchars() 被调用。
如果isCopy非空,则有:当一个副本被创建,*isCopy被设置为JNI_TRUE;如果副本创建失败,*isCopy被设置为JNI_FALSE
参数:
env:JNI接口指针
string:java字符串对象
isCopy:指向布尔值的指针
返回:
返回一个指向unicode字符串的指针,如果操作失败,返回NULL

void ReleaseStringChars(JNIEnv *env, jstring string,const jchar *chars);
通知虚拟机本地代码不再需要使用对应字符串指针,chars参数是通过GetStringChars()获取的一个指向string的指针,
参数:
env:JNI接口指针
string:java字符串对象
chars:指向unicode字符串的指针

jstring NewStringUTF(JNIEnv *env, const char *bytes);
创建一个新的java.lang.String 对象,根据modifiedUTF-8编码的字符串数组
参数:
env:JNI接口指针
bytes:指向modifiedUTF-8字符串的指针
返回
返回一个java字符串对象,如果字符串不能被创建返回NULL
抛出异常
OutOfMemoryError 如果系统内存溢出

jsize GetStringUTFLength(JNIEnv *env, jstring string);
返回字符串的长度
参数:
env:JNI接口指针
string:java字符串对象
返回:
返回字符串的UTF-8长度

const char * GetStringUTFChars(JNIEnv *env, jstring string,jboolean *isCopy);
返回指向modifiedUTF-8编码的字符的数组的指针,该数组长期有效直到ReleaseStringUTFChars()的调用。
如果isCopy非空,则有:当一个副本被创建,*isCopy被设置为JNI_TRUE;如果副本创建失败,*isCopy被设置
参数:
env:JNI接口指针
string:java字符串对象
isCopy:指向布尔值的指针
返回:
返回一个指向modified UTF-8字符串的指针,如果操作失败,返回NULL

void ReleaseStringUTFChars(JNIEnv *env, jstring string,const char *utf);
通知虚拟机本地代码不再需要访问utf,utf是一个由GetStringUTFChars()产生的字符串的指针
参数:
env:JNI接口指针
string:java字符串对象
utf:指向modified UTF-8字符串指针

void GetStringRegion(JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf);
在给定的str中复制len长度的,从偏移量start开始的unicode字符串到buffer
抛出StringIndexOutOfBoundsException 如果索引溢出。

void GetStringUTFRegion(JNIEnv *env, jstring str, jsize start, jsize len, char *buf);
在给定的str中复制len长度的,从偏移量start开始的modified UTF-8字符串到buffer
抛出StringIndexOutOfBoundsException 如果索引溢出。

const jchar * GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy);
void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *carray);
从字面上看,这两个函数类似于 Get/ReleaseStringChars函数,如果可以的话,虚拟机返回一个指向string元素的指针,否则,将创建一个副本。然而,这两个函数的使用有所限制。在Get/ReleaseStringCritical中间的代码段,本地代码不能使用任意的JNI调用或者引起当前线程阻塞。相当于临界区保护。
后续的Get/ReleasePrimitiveArrayCritical与这里的限制条件类似。

10、数组操作
jsize GetArrayLength(JNIEnv *env, jarray array);
返回数组的元素个数。
参数:
env:JNI接口指针
array:java数组对象。
返回:
数组的长度。

jobjectArray NewObjectArray(JNIEnv *env, jsize length,jclass elementClass, jobject initialElement);
在elementClass中创建新的数组,所有的元素被初始化为initialElement。
参数:
env:JNI接口指针
length:数组大小
elementClass:数组元素类
initialElement:初始化值
返回:
返回一个java数组对象,如果数组无法被创建,返回NULL
抛出异常:
OutOfMemoryError:如果系统内存溢出。

jobject GetObjectArrayElement(JNIEnv *env,jobjectArray array, jsize index);
返回Object数组的一个元素
参数:
env:JNI接口指针
array:java数组
index:数组索引
返回:
返回一个java对象
抛出异常:
ArrayIndexOutOfBoundsException:如果索引无效。

void SetObjectArrayElement(JNIEnv *env, jobjectArray array,jsize index, jobject value);
设置object数组的元素
参数:
env:JNI接口指针
array:java数组
index:数组索引
value:所要设置的值
抛出异常:
ArrayIndexOutOfBoundsException:索引无效
ArrayStoreException:设置的值不是数组的元素类的子类

ArrayType NewArray(JNIEnv *env, jsize length);
构建一个新的初始的数组对象。
NewArray Routines
Array Type
NewBooleanArray()
jbooleanArray
NewByteArray()
jbyteArray
NewCharArray()
jcharArray
NewShortArray()
jshortArray
NewIntArray()
jintArray
NewLongArray()
jlongArray
NewFloatArray()
jfloatArray
NewDoubleArray()
jdoubleArray
参数:
env:JNI接口指针
length:数组长度
返回:
返回java数组,如果该数组无法被创建返回NULL

NativeType *GetArrayElements(JNIEnv *env,ArrayType array, jboolean *isCopy);
获取初始数组的指针,该指针长期有效直到对应的ReleaseArrayElements()被调用。
返回的数组可能是java数组的拷贝,在返回的数组上有所改变时,不会反映到原始的数组,直到 ReleaseArrayElements()被调用。
如果isCopy非空,则有:当一个副本被创建,*isCopy被设置为JNI_TRUE;如果副本创建失败,*isCopy被设置
GetArrayElements Routines
Array Type
Native Type
GetBooleanArrayElements()
jbooleanArray
jboolean
GetByteArrayElements()
jbyteArray
jbyte
GetCharArrayElements()
jcharArray
jchar
GetShortArrayElements()
jshortArray
jshort
GetIntArrayElements()
jintArray
jint
GetLongArrayElements()
jlongArray
jlong
GetFloatArrayElements()
jfloatArray
jfloat
GetDoubleArrayElements()
jdoubleArray
jdouble
对于GetBooleanArrayElements()而言,它总是返回一个指向jbooleans的指针,而每个字节代表一个元素。
其他类型的数组在内存中是连续的。

参数:
env:JNI接口指针
array:java字符串对象
isCopy:指向boolean的指针。
返回:
返回指向数组元素的指针,如果操作失败返回NULL

void ReleaseArrayElements(JNIEnv *env,ArrayType array, NativeType *elems, jint mode);
该系列函数通知虚拟机本地代码不再需要访问elems指针,elems参数由GetArrayElements() 函数获得,如果需要,该函数复制所有的在elems上的变换到原始的数组元素上去。
mode参数提供了数组buffer应该怎样被释放。如果elems不是array的一个副本,mode并没有什么影响。否则,有如下的区别:
mode
actions
0
copy back the content and free the elems buffer复制所有内容并且释放elems buffer
JNI_COMMIT
copy back the content but do not free the elems buffer复制所有的内容但不要释放elems buffer
JNI_ABORT
free the buffer without copying back the possible changes 释放buffer当不要复制内容的变化
大多数情况下,编程人员把0复制给mode参数。
ReleaseArrayElements Routines
Array Type
Native Type
ReleaseBooleanArrayElements()
jbooleanArray
jboolean
ReleaseByteArrayElements()
jbyteArray
jbyte
ReleaseCharArrayElements()
jcharArray
jchar
ReleaseShortArrayElements()
jshortArray
jshort
ReleaseIntArrayElements()
jintArray
jint
ReleaseLongArrayElements()
jlongArray
jlong
ReleaseFloatArrayElements()
jfloatArray
jfloat
ReleaseDoubleArrayElements()
jdoubleArray
jdouble
参数:
env:JNI接口指针
array:JAVA数组对象
elems:指向数组元素的指针
mode:释放模式

void GetArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, NativeType *buf);
复制初始数组给buffer
GetArrayRegion Routine
Array Type
Native Type
GetBooleanArrayRegion()
jbooleanArray
jboolean
GetByteArrayRegion()
jbyteArray
jbyte
GetCharArrayRegion()
jcharArray
jchar
GetShortArrayRegion()
jshortArray
jhort
GetIntArrayRegion()
jintArray
jint
GetLongArrayRegion()
jlongArray
jlong
GetFloatArrayRegion()
jfloatArray
jloat
GetDoubleArrayRegion()
jdoubleArray
jdouble
参数:
env:JNI接口指针
array:JAVA数组
start:开始索引
len:需要复制的长度
buf:目标buffer
异常:
ArrayIndexOutOfBoundsException:如果索引无效

void SetArrayRegion(JNIEnv *env, ArrayType array,jsize start, jsize len, const NativeType *buf);
把值从buffer复制到初始数组
SetArrayRegion Routine
Array Type
Native Type
SetBooleanArrayRegion()
jbooleanArray
jboolean
SetByteArrayRegion()
jbyteArray
jbyte
SetCharArrayRegion()
jcharArray
jchar
SetShortArrayRegion()
jshortArray
jshort
SetIntArrayRegion()
jintArray
jint
SetLongArrayRegion()
jlongArray
jlong
SetFloatArrayRegion()
jfloatArray
jfloat
SetDoubleArrayRegion()
jdoubleArray
jdouble
参数:
env:JNI接口指针
array:java数组
start:开始索引
len:需要复制的长度
buf:源buffer
异常:
ArrayIndexOutOfBoundsException:如果索引无效

void * GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy);
void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode);
这两个与Get/ReleaseArrayElements类似,如果可以的话,虚拟机返回指向初始数组的指针,否则,将创建副本。然而使用时有限制条件。
在调用GetPrimitiveArrayCritical之后,在调用ReleasePrimitiveArrayCritical之前,本地代码不能运行多一个扩展周期的时间。我们必须把在这两个函数之间的代码当作临界区。在临界区内,本地代码不能调用其他JNI函数,或者系统调用其他会导致当前线程阻塞等待其他现场的函数,比如,当前线程不能调用read来读取正在被其他java线程所写入的流。
这些限制很大程度上使得本地方法会获得一个array的非复制版本,即使虚拟机不知道pinning。比如,当本地代码有通过GetPrimitiveArrayCritical获得的一个指向数组的指针时,虚拟机会临时停止垃圾回收器的工作。
允许嵌套使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值