简体   繁体   中英

What causes the JNI error "use of deleted local reference"?

I have an Android app where the following C method is called when the app starts (in Activity.onCreate ).

extern "C"
JNIEXPORT jstring JNICALL
Java_com_google_oboe_test_oboetest_MainActivity_stringFromJNI(
    JNIEnv *env,
    jobject instance) {

    jclass sysclazz = env->FindClass("java/lang/System");
    jmethodID getPropertyMethod = env->GetStaticMethodID(sysclazz, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
    jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, "os.name");
    return result;
}

When this method is called the app crashes and I get the error:

JNI DETECTED ERROR IN APPLICATION: use of deleted local reference 0xd280e8d5

Step debugging shows that this line causes the crash:

jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, "os.name");

What causes this error? And how can I call System.getProperty("os.name") using JNI without getting this error?

The issue is that env->CallStaticObjectMethod is expecting a jstring as its 3rd argument and is instead being supplied with a string literal.

Creating a jstring first

jstring arg = env->NewStringUTF("os.name");
jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, arg);

fixed the problem.

In my case, I was using a local reference that was created in a function and was used in another function. For example:

void funA(){
    jclass localClass = env->FindClass("MyClass");
}

The above statement returns a local reference of jclass. Suppose we store this in a global variable and use it in another function funB after funA is completed, then this local reference will not be considered as valid and will return "use of deleted local reference error".

To resolve this we need to do this:

jclass localClass = env->FindClass("MyClass");
jclass globalClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass));

First, get the local reference and then get the global reference from local reference. globalClass can be used globally (in different functions).

Read Local and global references

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM