【发布时间】:2020-05-01 04:18:57
【问题描述】:
更新我的项目以支持 Android 10 后,在 JNI 级别产生了与 Android 10 中的非 SDK 接口限制相关的崩溃:
JNI DETECTED ERROR IN APPLICATION: JNI SetIntField called with pending exception java.lang.NoSuchFieldError: no "I" field "value" in class "Ljava/lang/Integer;" or its superclasses
来自这部分代码:
jclass clazz = (*env)->GetObjectClass(env, outputObj);
jfieldID mi = (*env)->GetFieldID(env, clazz, "value", "I");
(*env)->SetIntField(env, outputObj, mi, pListLen);
为了解决这个问题,我将其替换为:
jclass clazz = (*env)->GetObjectClass(env, outputObj);
jmethodID intValueMethod = (*env)->GetMethodID(env, clazz, "intValue", "()I");
jint result = (*env)->CallIntMethod(env, outputObj,intValueMethod,pListLen);
之后我的应用程序不会崩溃并正确找到整数值,但我想使用相同的方法 SetIntField 在 Java 代码上设置结果整数。
能否请您给我一种在 Java 部分设置结果的方法或方法。
【问题讨论】:
-
您不应该更改
Integer对象的内部值,这会破坏各种不变量!请解释为什么你认为你需要这样做;也许我们可以找到其他方法。 -
感谢您的回复, outputObj 稍后将在 java 部分中使用,但在 Android 10 更新之前,SetIntField 可以完美地工作,所以我想如果有另一种方法来设置我的outputObj 将其返回到 java 部分
-
使用
Integer#valueOf(int)重载来构造一个新的Integer对象。 -
“在 Android 10 更新之前,SetIntField 可以完美地工作” 之前工作的事实对我来说听起来像是一个错误。
Integers 应该是不可变的,因为例如如果您对 Integer.valueOf,则可以重复使用相同的Integer实例。 -
@Botje 我已经尝试过您的代码,但 outputObj 没有改变。这是我想做的:我想通过这个值设置 outputObj size_t pListLen = (size_t)(*env)->GetArrayLength(env, List);在这部分我将值设置为 java 部分: jclass clazz = (*env)->GetObjectClass(env, outputCidpuBufLen); jmethodID valueOfMethod = (*env)->GetStaticMethodID(env,clazz, "valueOf", "(I)Ljava/lang/Integer;"); (*env)->CallStaticObjectMethod(env,clazz, valueOfMethod, (jint)pListLen);最后在java部分没有出现新值,这真是奇怪的行为
标签: android java-native-interface android-10.0