JNI常见报错及解决方案汇总
一 JNI ERROR (app bug): accessed stale local reference
原因分析
在Android NDK编程时,要使用到.so文件,so文件使用C语言编写的。当在C程序中调用Java类时,第一次调用时没问题的,但第二次调用的时候就失败了。原因就是在JNI中,使用指针指向某一个Java对象的时候,由于Android的垃圾回收机制(Garbage Collector),Java对象会被回收,如果java对象被回收的话,那么指针指向的对象就会为空或者不存在,从而提示JNI ERROR:accessed stale(陈旧的,落后的) local reference,意思就是变量已经不存在了。
解决方案
要解决这个问题,就需要把Java对象定义成静态的,并把它转换为全局变量,这样可以避免Java对象被回收(在Android4.0以后,静态变量也会被回收,但概率较小),从而避免错误的发生。具体如下所示:
原来的调用方式
jobject myJavaObject; myJavaObject = (*jniEnv)->NewObject(jniEnv, obj_class, construction_id);
修改后的调用方式
static jobject myJavaObject; jobject obj = jobject obj = (*jniEnv) ->NewObject(jniEnv,obj_class,construction_id); myJavaObject = (jobject) (*jniEnv) ->NewGlobalRef(jniEnv,obj);
二 JNI ERROR (app bug): accessed stale global reference
原因分析
在使用全局变量的同时,在某一个函数中用了同名同类型的局部变量,并且给这个局部变量赋值。使得其他函数在用这个全局变量时,这个全局变量没有被赋值。
