直奔主题,Android L 引入了 ART 作为默认运行时。我有一个示例应用程序,基本上是一个文档查看器。大部分文档查看代码,包括后退按钮、搜索等,都是用 C 语言编写的,Android App 使用 JNI 接口。我更新了我的代码以使其为 Android L 构建,它似乎可以很好地打开文档。但是,当按下后退按钮并关闭文档时,应用程序似乎崩溃了,并且看到了以下回溯:
I/DEBUG ( 1390): Abort message: 'art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: JNI CallIntMethodV called with pending exception 'java.lang.StackOverflowError' thrown in unknown throw location'
I/DEBUG ( 1390): backtrace:
I/DEBUG ( 1390): #00 pc 000390d0 /system/lib/libc.so (tgkill+12)
I/DEBUG ( 1390): #01 pc 0001636d /system/lib/libc.so (pthread_kill+64)
I/DEBUG ( 1390): #02 pc 00016e41 /system/lib/libc.so (raise+10)
I/DEBUG ( 1390): #03 pc 00013cdd /system/lib/libc.so (__libc_android_abort+36)
I/DEBUG ( 1390): #04 pc 000125ac /system/lib/libc.so (abort+4)
I/DEBUG ( 1390): #05 pc 00230fe9 /system/lib/libart.so (art::Runtime::Abort()+188)
I/DEBUG ( 1390): #06 pc 000b9571 /system/lib/libart.so (art::LogMessage::~LogMessage()+1360)
I/DEBUG ( 1390): #07 pc 000c28cd /system/lib/libart.so (art::JniAbort(char const*, char const*)+1124)
I/DEBUG ( 1390): #08 pc 000c2e11 /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
I/DEBUG ( 1390): #09 pc 000c65e9 /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1952)
I/DEBUG ( 1390): #10 pc 000cc8eb /system/lib/libart.so (art::CheckJNI::CallIntMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+42)
按下后退按钮后,当文件描述符应该关闭时,调用 CallIntMethodV,最终检查 JNI 失败。相同的代码似乎在 dalvik 上工作得很好。我必须添加以下标志以使 JNI 代码能够为 Android L 预览版正常编译:
-Wno-switch -Wno-sizeof-pointer-memaccess
LOCAL_DISABLE_FORMAT_STRING_CHECKS := true
关键是为什么它现在开始在艺术上失败,而不是在 dalvik 上。CallIntMethodV 中导致问题或编译器严格性的任何特定更改是否会导致引发此类错误?任何指针。如果需要,我很乐意提供更多详细信息。
更新:我暂时禁用了对本机代码调用 JNI 的文件关闭函数的调用,我现在似乎没有看到任何崩溃。