调用CallStaticObjectMethod报出JNI DETECTED ERROR IN APPLICATION: jclass is an invalid local reference:

    xiaoxiao2021-12-14  16

    最近遇到一个JNI的问题,一套代码在Android上首次运行是OK的,但是在第二次运行之后设备就会崩溃,查看logcat发现报JNI DETECTED ERROR IN APPLICATION错误。

    (1)错误: accessed stale local reference 0x57200019 (index 6 in a table of size 6) JNI DETECTED ERROR IN APPLICATION: jclass is an invalid local reference in call to CallStaticObjectMethod from void com.org.vincent.ccalljava.JNI.getTime() JNI DETECTED ERROR IN APPLICATION: calling static method xxxx with CallxxxxMethodV in call to CallxxxxMethodV

    综合上面这个错误显示是CallStaticObjectMethod 的jclass 参数非法引用,网上找了一些相关问题的帖子,说明在JNI中有三种不用的引用方式,不同方式有不同的生命周期。结合本地代码,发现最有可能的就是jclass 实例不能用局部引用,必须使用全局引用保持jclass实例在函数退出后还具有生命周期。

    改变前:

    if(JNI == NULL) { JNI = (*jniEnv)->FindClass(jniEnv,"com/org/vincent/ccalljava/JNI"); if(JNI == NULL){ return -1; } __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitProvider Begin 2 ok" ); }

    改成后:

    if(JNI == NULL) { jclass localRef; localRef = (*jniEnv)->FindClass(jniEnv,"com/org/vincent/ccalljava/JNI"); if(JNI == NULL){ return -1; } //创建一个jclass 的全局引用 JNI=(*jniEnv)->NewGlobalRef(jniEnv,localRef); __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitProvider Begin 2 ok" ); }

    JNI是在jni中定义的全局变量,如果这个函数一旦执行完退出,那么JNI指向的jclass类型内存可能会被GC回收,那么JNI就指向非法地址。 事后验证判定是对的 参考:blog

    转载请注明原文地址: https://ju.6miu.com/read-971063.html

    最新回复(0)