创建字符串
jstring (*NewStringUTF)(JNIEnv*, const char*);
通过调用
NewStringUTF(...)
函数,创建 Unicode 字符串,会构建一个新的java.lang.String
字符串对象。这个新创建的字符串会自动转换成 Java 支持的 Unicode 编码。如果 JVM 不能为构造 java.lang.String 分配足够的内存,NewStringUTF 会抛出一个 OutOfMemoryError 异常,并返回 NULL。我们不必检查它的返回值,如果NewStringUTF 创建 java.lang.String 失败,OutOfMemoryError 这个异常会在 caller 中抛出。如果 NewStringUTF 创建 java.lang.String 成功,则返回一个 JNI 引用,这个引用指向新创建的 java.lang.String 对象。
(*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
GetStringUTFChars
从 Java 字符串转换成 C/C++ 字符串,使用 GetStringUTFChars(...)
函数。
这是一个 JNI 函数,Java 默认使用 Unicode 编码,而 C/C++ 默认使用 UTF 编码,所以在本地代码中操作字符串的时候,必须使用合适的 JNI 函数把 jstring 转换成 C 风格的字符串。JNI 支持字符串在 Unicode 和 UTF-8 两种编码之间转换,GetStringUTFChars 可以把一个 jstring 指针(指向 JVM 内部的 Unicode 字符序列)转换成一个UTF-8 格式的 C 字符串。我们通过
GetStringUTFChars(...)
正确取得了 JVM 内部的字符串内容。
// JNIEnv 函数表指针
// jstring 代表 Java 传递给本地代码的字符串指针
// 取值 JNI_TRUE 和 JNI_FALSE,如果值为 JNI_TRUE,表示返回 JVM 内部源字符串的一份拷贝,并为新产生的字符串分配内存空间。如果值为 JNI_FALSE,表示返回 JVM 内部源字符串的指针,意味着可以通过指针修改源字符串的内容,不推荐这么做,因为这样做就打破了 Java 字符串不能被修改的规定。但我们在开发当中,并不关心这个值是多少,通常情况下这个参数填 NULL 即可。
const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
Tips:
GetStringUTFChars()
与 ReleaseStringUTFChars()
总是成对出现。
const char *version = (*env)->GetStringUTFChars(env, buildVersion, NULL);
if (!version) {
LOGE("Unable to get version string @ line %d", __LINE__);
return;
}
LOGI("Android Version - %s", version);
(*env)->ReleaseStringUTFChars(env, buildVersion, version);
// we are called from JNI_OnLoad, so got to release LocalRef to avoid leaking
(*env)->DeleteLocalRef(env, buildVersion);
异常检查
调用完 GetStringUTFChars(...)
之后不要忘记安全检查,因为 JVM 需要为新诞生的字符串分配内存空间,当内存空间不够分配的时候,会导致调用失败,失败后 GetStringUTFChars(...)
会返回 NULL,并抛出一个OutOfMemoryError
异常。JNI 的异常和 Java 中的异常处理流程是不一样的,Java 遇到异常如果没有捕获,程序会立即停止运行。而 JNI 遇到未决的异常不会改变程序的运行流程,也就是程序会继续往下走,这样后面针对这个字符串的所有操作都是非常危险的,因此,我们需要用 return 语句跳过后面的代码,并立即结束当前方法。
const char *version = (*env)->GetStringUTFChars(env, buildVersion, NULL);
if (!version) {
LOGE("Unable to get version string @ line %d", __LINE__);
return;
}
GetStringChars
和 ReleaseStringChars
用于获取和释放以 Unicode 格式编码的字符串
网友评论