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

原因分析

在使用全局变量的同时,在某一个函数中用了同名同类型的局部变量,并且给这个局部变量赋值。使得其他函数在用这个全局变量时,这个全局变量没有被赋值。

经验分享 程序员 微信小程序 职场和发展