JNI ERROR(app bug):在本机方法中删除本地引用时访问过时的本地引用0x2d

时间:2017-08-04 15:17:16

标签: java android c++ android-ndk java-native-interface

在本机方法中,我声明了一个jstring本地引用,在完成之后,我使用DeleteLocalRef删除它ref,但它总是报告错误。我已经阅读了很多关于JNI参考的网站,但是大多数主题都表明错误可能是通过使用本地引用交叉方法引起的,但在我的情况下,jstring对象被声明并且在同一个函数中,所以我和#39; m混淆了我的代码有什么问题。 以下是我的代码:

 //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);
}

here中的logcat。

0 个答案:

没有答案