多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
除了前边介绍的GetStringUTF, ReleaseStringUTFChars以及NewStringUTF, JNI还支持很多其他的字符串操作相关的函数。 GetStringChars和ReleaseStringChars处理Unicode格式的字符串。在操作系统支持Unicode格式的原生字符串时会变得很有用。 UTF-8字符串通常以'\0'结尾,而Unicode字符串则不是。如果你想获取一个jstring引用中的Unicode字符的个数,可以使用用GetStringLength。如果你想知道以UTF-8格式保存一个jstring需要多少个字节,你可以使用GetStringUTFChars或者直接调用C函数strlen,或者直接在jstring对象引用上调用GetStringUTFLength函数。 GetStringChars和GetStringUTFChars的第三个参数需要额外解释一下,下面我们来看下它们的函数签名: `const jchar* GetStringChars(JNIEnv* env, jstring str, jboolean* isCopy)` 如果返回的字符串是原来的java.lang.String的一份拷贝, 在GetStringChars返回之后,isCopy指向的内存地址将会被设置为JNI_TRUE。而如果返回的字符串指针直接指向原来的java.lang.String对象,则该地址会被设置为JNI_FALSE.如果返回了JNI_FALSE, 则原生代码将不能改变返回的字符串,因为改变了这个字符串,原来的java字符串也会被修改,这违背了java.lang.String实例不可改变的原则。 通常你可以直接传递NULL给isCopy来告诉Java虚拟机你不在乎返回的字符串是否指向原来Java的String对象。 我们几乎无法预测虚拟机是否拷贝了给定的Java字符串对象。因此开发者必须假定GetStringChars操作是一个耗时且占用了与给定字符串长度相同的字符空间,在通常的Java虚拟机实现中,垃圾收集器都会在堆中重定位对象。一旦一个指向java.lang.String对象指针被传递给了原生代码,垃圾收集器就不能重定向该对象了,而必须换一种处理方式,虚拟机不许绑定并跟踪这个java.lang.String实例。而过多的这种绑定会造成大量的内存碎片,虚拟机实现必须根据它自己的状况决定是为每一个GetStringChars执行字符串拷贝工作或者使用绑定跟踪策略。 在你不再使用从GetStringChars函数返回的字符串时,请记得使用ReleaseStringChars释放掉它。不论isCopy是被设置为JNI_TRUE还是JNI_FALSE,ReleaseStringChars都需要被调用。要么是释放拷贝的内存,要么是解绑定字符串实例(这样垃圾回收器就可以执行重定位与回收操作了)。