我从这里购买了绝对初学者和温度转换器应用程序的Android应用程序的hello world应用程序 两者在模拟器上运行正常,但当我尝试在Samsung Note 2上运行它时,LogCat上出现错误
02-08 07:22:18.665: E/dalvikvm(30944): JNI ERROR (app bug): accessed stale local reference 0xbc00021 (index 8 in a table of size 8)
02-08 07:22:18.665: E/dalvikvm(30944): VM aborting
02-08 07:22:18.665: A/libc(30944): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 30944 (oid.temperature)
Run Code Online (Sandbox Code Playgroud)
两个应用程序都使用标题打开显示布局,但在布局中不显示任何其他视图
样品运行良好
设备:备注2 Samsung-gt_n7100
IDE:Eclipse版本3.8
操作系统:64位Windows 7
Ale*_*xey 60
因为android 4.0垃圾收集器被改变了.现在它在垃圾收集过程中移动对象,这可能会导致很多问题.
想象一下,你有一个指向一个对象的静态变量,然后这个对象被gc移动.由于android使用java对象的直接指针,这意味着你的静态变量现在指向内存中的随机地址,没有被任何对象占用或被不同类型的对象占用.这几乎可以保证下次使用此变量时您将获得EXC_BAD_ACCESS.
所以android会给你JNI ERROR(app bug)错误,以防止你获得可判断的EXC_BAD_ACCESS.现在有两种方法可以避免这种错误.
您可以将清单中的targetSdkVersion设置为版本11或更低版本.这将启用JNI错误兼容模式并完全防止任何问题.这就是您的旧示例正在运行的原因.
在通过调用env-> NewGlobalRef(ref)存储它们之前,可以避免使用指向java对象的静态变量或使jobject引用全局化.
也许最重要的例子是保持jclass对象.通常,您将在JNI_OnLoad期间初始化静态jclass变量,因为只要应用程序正在运行,类对象就会保留在内存中.
此代码将导致崩溃:
static jclass myClass;
JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM * vm, void * reserved) {
myClass = env->FindClass("com/example/company/MyClass");
return JNI_VERSION_1_6;
}
Run Code Online (Sandbox Code Playgroud)
虽然这段代码运行良好:
static jclass myClass;
JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM * vm, void * reserved) {
jclass tmp = env->FindClass("com/example/company/MyClass");
myClass = (jclass)env->NewGlobalRef(tmp);
return JNI_VERSION_1_6;
}
Run Code Online (Sandbox Code Playgroud)
有关更多示例,请参阅Marek Sebera提供的链接:http://android-developers.blogspot.cz/2011/11/jni-local-reference-changes-in-ics.html
| 归档时间: |
|
| 查看次数: |
25919 次 |
| 最近记录: |