【发布时间】:2018-11-23 10:43:51
【问题描述】:
美好的一天。编写了应该设置键值的代码。
extern "C" JNIEXPORT jboolean JNICALL Java_com_example_woodman_testlibsettingsv2_frmMain_SetSystemKeysString(JNIEnv *env, jobject instance, jstring key_Name_) {
const char *key_Name = env->GetStringUTFChars(key_Name_, 0);
// TODO
jclass secClass = env->FindClass("android/provider/Settings$System");
jmethodID secMid = env->GetStaticMethodID(secClass, "putString", "(Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;Ljava/lang/String;)Z");
jclass activityThread = env->FindClass("android/app/ActivityThread");
jmethodID currentActivityThread = env->GetStaticMethodID(activityThread, "currentActivityThread", "()Landroid/app/ActivityThread;");
jobject at = env->CallStaticObjectMethod(activityThread, currentActivityThread);
jmethodID getApplication = env->GetMethodID(activityThread, "getApplication", "()Landroid/app/Application;");
jobject context = env->CallObjectMethod(at, getApplication);
jclass c_context = env->FindClass("android/content/Context");
jmethodID m_get_content_resolver = env->GetMethodID(c_context, "getContentResolver", "()Landroid/content/ContentResolver;");
jobject o_content_resolver;
o_content_resolver = env->CallObjectMethod(context, m_get_content_resolver);
jstring jStringParam = env->NewStringUTF(key_Name);
jboolean jStringKey = env->CallStaticBooleanMethod(secClass, secMid, o_content_resolver, jStringParam, env->NewStringUTF("1"));
env->DeleteLocalRef(jStringParam);
return jStringKey;
}
但是当我尝试执行时,我得到一个错误。
E/stlibsettingsv: JNI ERROR (app bug): attempt to use stale Local 0x31 (should be 0x39)
A/stlibsettingsv: java_vm_ext.cc:542] JNI DETECTED ERROR IN APPLICATION: use of deleted local reference 0x31
java_vm_ext.cc:542] from boolean com.example.woodman.testlibsettingsv2.frmMain.SetSystemKeysString(java.lang.String)
java_vm_ext.cc:542] "main" prio=5 tid=1 Runnable
A/stlibsettingsv: java_vm_ext.cc:542] | group="main" sCount=0 dsCount=0 flags=0 obj=0x7968c450 self=0x74e3014c00
java_vm_ext.cc:542] | sysTid=32691 nice=-10 cgrp=default sched=0/0 handle=0x7568948548
java_vm_ext.cc:542] | state=R schedstat=( 316288736 11800419 156 ) utm=29 stm=2 core=5 HZ=100
java_vm_ext.cc:542] | stack=0x7fe34db000-0x7fe34dd000 stackSize=8MB
java_vm_ext.cc:542] | held mutexes= "mutator lock"(shared held)
java_vm_ext.cc:542] native: #00 pc 00000000003c26c0 /system/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+220)
每个人都有问题吗?
我阅读了很多论坛和网站。任何地方都没有解决办法。 谢谢。
添加: 此行会导致错误。
jboolean jStringKey = env->CallStaticBooleanMethod(secClass, secMid, o_content_resolver, jStringParam, env->NewStringUTF("1"));
所有其余的工作正常。调用 putString 方法的问题。
【问题讨论】:
-
问题中没有足够的信息。例如,哪一行代码触发了崩溃?
key_Name_的值在哪里赋值,该引用在哪里被删除? -
这段代码看起来很奇怪,你不释放
key_Name但DeleteLocalRef(jStringParam)没有意义。没关系。使用 ndk-stack 查找导致崩溃的行。 -
@AlexCohn 在帖子中添加了解释
-
您进行零错误检查,因此您不知道首先失败的是什么。您的
findClass()或getStaticMethodId()调用之一可能失败,或者您的Call*Method()调用之一引发异常,但由于您从不检查,所以您不知道。 -
如果你注释掉
env->DeleteLocalRef(jStringParam),它仍然会以同样的方式崩溃吗?
标签: android c++ android-ndk java-native-interface