Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JNI错误(应用程序错误):在本机方法中删除本地引用时访问了过时的本地引用0x2d_Java_Android_C++_Android Ndk_Java Native Interface - Fatal编程技术网

Java JNI错误(应用程序错误):在本机方法中删除本地引用时访问了过时的本地引用0x2d

Java JNI错误(应用程序错误):在本机方法中删除本地引用时访问了过时的本地引用0x2d,java,android,c++,android-ndk,java-native-interface,Java,Android,C++,Android Ndk,Java Native Interface,在本机方法中,我声明了一个jstringlocal引用,完成后,我使用DeleteLocalRef删除它ref,但它总是报告一个错误。我已经阅读了许多关于JNI引用的网站,但是大多数主题都认为错误可能是由于在方法中使用本地引用引起的,但是在我的例子中,jstring对象是声明的,并且在同一个函数中,所以我混淆了我的代码的错误。 下面是我的代码: //jObj is a global reference int GetStringField( JNIEnv *env,jobject&

在本机方法中,我声明了一个
jstring
local引用,完成后,我使用DeleteLocalRef删除它ref,但它总是报告一个错误。我已经阅读了许多关于JNI引用的网站,但是大多数主题都认为错误可能是由于在方法中使用本地引用引起的,但是在我的例子中,
jstring
对象是声明的,并且在同一个函数中,所以我混淆了我的代码的错误。 下面是我的代码:

 //jObj is a global reference
 int GetStringField( JNIEnv *env,jobject& jObj, string strFieldName, string& strValue ){
    g_nTestTime++;
    LOGD("GetStringField  %d", g_nTestTime);
    strValue = "";

    jclass clazz = NULL;
    jfieldID fid;
    jstring j_str = NULL;
    const char *c_str = NULL;

    clazz = env->GetObjectClass(jObj);
    if (clazz == NULL) {
        LOGE("Get jObj class object failed in %s!", "GetStringField");
        return -1;
    }

    fid = env->GetFieldID(clazz, strFieldName.c_str(), "Ljava/lang/String;");
    if (fid == NULL) {
        env->DeleteLocalRef(clazz);
        LOGE("can not found %s ref in %s!", strFieldName.c_str(), "GetStringField");
        return -1;
    }

    j_str = (jstring)env->GetObjectField(jObj, fid);
    if (NULL == j_str)
    {
        LOGE("Get String object [%s] value failed in %s!", strFieldName.c_str(), "GetStringField");
        env->DeleteLocalRef(clazz);
        return -1;
    }

    c_str = env->GetStringUTFChars(j_str, NULL);
    if (c_str == NULL) {
        return -1;
    } else{
        strValue = c_str;
    }

    env->ReleaseStringUTFChars(j_str, c_str);

    LOGD("Before env->DeleteLocalRef(clazz)!"); 
    DumpReferenceTables(env);

    env->DeleteLocalRef(clazz);

    LOGD("After env->DeleteLocalRef(clazz)!");
    DumpReferenceTables(env); // the dump shows 'j_str' still in the local reference table

    env->DeleteLocalRef(j_str); //JNI ERROR (app bug): accessed stale local reference 0x2d (index 11 in a table of size 10)

    LOGD("After env->DeleteLocalRef(j_str)!");
    DumpReferenceTables(env);

    return  0;
}
DumpReferenceTables是一个用于转储ReferenceTables的VMDebug类方法,下面是他的代码:

void DumpReferenceTables(JNIEnv *env)
{
    jclass vm_class = env->FindClass("dalvik/system/VMDebug");
    if(NULL == vm_class)
        return ;
    jmethodID dump_mid = env->GetStaticMethodID( vm_class, "dumpReferenceTables", "()V" );
    if(NULL == dump_mid)
        return ;
    env->CallStaticVoidMethod( vm_class, dump_mid );
    env->DeleteLocalRef(vm_class);
}

日志输入。

请参见此;-
//jObj是一个全局引用
?这是如何保存的?我建议使用PushLocalFrame()和PopLocalFrame()代替LocalRef微观管理。你可以用C++来包装,以充分利用这一点;code>//jObj是一个全局引用?这是如何保存的?我建议使用PushLocalFrame()和PopLocalFrame()代替LocalRef微观管理。你可以用C++来包装它,以利用