Android JNI 检测到应用程序错误:调用 JNI GetMethodID 时出现未决异常
Android JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception
我正在尝试 运行 Google 的 OCR Tesseract 与我的 android 项目。我已经将 tesseract 与 android-ndk 兼容,并且在尝试 运行 android 项目后收到此错误。
我的环境如下
- Android 5.1.1
- android-ndk-r10e windows
- android-sdk-r22
作为参考,我是根据此处列出的示例构建的 Example Link
提前致谢!
这是我的 logcat 结果的片段:
I/DEBUG ( 182): Revision: '0'
I/DEBUG ( 182): ABI: 'arm'
I/DEBUG ( 182): pid: 20291, tid: 20337, name: JavaBridge >>> com.enterprisem
obility.OCR <<<
I/DEBUG ( 182): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
I/DEBUG ( 182): Abort message: 'art/runtime/check_jni.cc:65] JNI DETECTED ERR
OR IN APPLICATION: JNI GetMethodID called with pending exception 'java.lang.NoSu
chFieldError' thrown in void com.googlecode.tesseract.android.TessBaseAPI.native
ClassInit():-2'
I/DEBUG ( 182): r0 00000000 r1 00004f71 r2 00000006 r3 00000000
I/DEBUG ( 182): r4 a0701db8 r5 00000006 r6 0000000b r7 0000010c
I/DEBUG ( 182): r8 00000000 r9 b486f520 sl a1c0ac00 fp 00000001
I/DEBUG ( 182): ip 00004f71 sp a07006d8 lr b6e503c5 pc b6e72f6c cpsr
60070010
I/DEBUG ( 182):
I/DEBUG ( 182): backtrace:
I/DEBUG ( 182): #00 pc 00039f6c /system/lib/libc.so (tgkill+12)
I/DEBUG ( 182): #01 pc 000173c1 /system/lib/libc.so (pthread_kill+52)
I/DEBUG ( 182): #02 pc 00017fd3 /system/lib/libc.so (raise+10)
I/DEBUG ( 182): #03 pc 00014795 /system/lib/libc.so (__libc_android_abor
t+36)
I/DEBUG ( 182): #04 pc 00012f44 /system/lib/libc.so (abort+4)
I/DEBUG ( 182): #05 pc 00228cd7 /system/lib/libart.so (art::Runtime::Abo
rt()+170)
I/DEBUG ( 182): #06 pc 000a7371 /system/lib/libart.so (art::LogMessage::
~LogMessage()+1360)
I/DEBUG ( 182): #07 pc 000b1b17 /system/lib/libart.so (art::JniAbort(cha
r const*, char const*)+1118)
I/DEBUG ( 182): #08 pc 000b2055 /system/lib/libart.so (art::JniAbortF(ch
ar const*, char const*, ...)+68)
I/DEBUG ( 182): #09 pc 000b530f /system/lib/libart.so (art::ScopedCheck:
:ScopedCheck(_JNIEnv*, int, char const*)+1346)
I/DEBUG ( 182): #10 pc 000b7755 /system/lib/libart.so (art::CheckJNI::Ge
tMethodID(_JNIEnv*, _jclass*, char const*, char const*)+36)
I/DEBUG ( 182): #11 pc 001332f7 /data/app/com.enterprisemobility.OCR-1/l
ib/arm/libtess.so (Java_com_googlecode_tesseract_android_TessBaseAPI_nativeClass
Init+46)
I/DEBUG ( 182): #12 pc 0000614d /data/dalvik-cache/arm/data@app@com.ente
rprisemobility.OCR-1@base.apk@classes.dex
W/ActivityManager( 536): Force finishing activity 1 com.enterprisemobility.OC
R/.MainActivity
I/DEBUG ( 182):
I/DEBUG ( 182): Tombstone written to: /data/tombstones/tombstone_07
Abort message比较清楚:你调用GetFieldID(cls, fieldName)
的字段名在你传给这个函数的class中不存在,但是您不检查该错误,而是继续调用其他 JNI 函数。不幸的是,您不能忽略此类错误。在调用 GetMethodID()
或 大多数 JNI 函数之前,您必须 调用ExceptionClear()
。
您可以使用 addr2line 查找对 getMethodID()
的具体调用崩溃,并据此推导出对 GetFieldID(cls, fieldName)
的调用失败。但我建议为所有 JNI 调用添加错误检查,因为明天其他函数可能会抛出异常。
很可能是您的 C++ 代码中错误地定义了 JNI 映射。 JNI 与 Java 在类型映射方面有非常严格的约定。例如,
在从 JNI 调用 Java 对象的方法之前,我们需要它的签名。所以方法:
long myMethod (int n, String s, int[] arr);
从具有签名的 JNI 中看到:
(ILJAVA/LANG/STRING;[I])J
您可以在此处阅读这些规则的非常全面的概述:
http://www.rgagnon.com/javadetails/java-0286.html
你应该使用 android NDK 中的 ndk-stack 工具来找出崩溃的位置。查看 link 关于 ndk stack。
adb logcat > /tmp/foo.txt
$NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump foo.txt
我也有同样的问题,弄得我很困惑 2 days.Finally 原因是我传递了错误的对象 type.For 例子,
java 代码是
public OverlayLine(int mWidth,List<GeoPoint> mPoints);
我注册了如下的jni方法:
gClass.mInitMethod = env->GetMethodID(gObject, "<init>", "(ILjava/lang/Object;)V");
并得到错误消息 Errol encounter.And 我修改了代码
gClass.mInitMethod = env->GetMethodID(gObject, "<init>", "(ILjava/util/List;)V");
和错误 gone.That 您应该传递精确的对象类型而不是 'Ljava/lang/Object;'。
调用 GetMethodID 时遇到类似问题:
JNI DETECTED ERROR IN APPLICATION: thread Thread[1,tid=15092,Runnable,Thread*=0x791c1b8000,peer=0x7278ab58,"main"] using JNI after critical get
... in call to GetMethodID
我使用 GetMethodID 之前调用了几次
inBufP = env->GetPrimitiveArrayCritical(jIn, NULL);
解法:
我可以通过将 GetPrimitiveArray 更改为 GetByteArrayElements
来修复本机崩溃
jboolean isCopy;
inBufP = env->GetByteArrayElements(jIn, &isCopy);
我正在尝试 运行 Google 的 OCR Tesseract 与我的 android 项目。我已经将 tesseract 与 android-ndk 兼容,并且在尝试 运行 android 项目后收到此错误。
我的环境如下
- Android 5.1.1
- android-ndk-r10e windows
- android-sdk-r22
作为参考,我是根据此处列出的示例构建的 Example Link
提前致谢!
这是我的 logcat 结果的片段:
I/DEBUG ( 182): Revision: '0'
I/DEBUG ( 182): ABI: 'arm'
I/DEBUG ( 182): pid: 20291, tid: 20337, name: JavaBridge >>> com.enterprisem
obility.OCR <<<
I/DEBUG ( 182): signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
I/DEBUG ( 182): Abort message: 'art/runtime/check_jni.cc:65] JNI DETECTED ERR
OR IN APPLICATION: JNI GetMethodID called with pending exception 'java.lang.NoSu
chFieldError' thrown in void com.googlecode.tesseract.android.TessBaseAPI.native
ClassInit():-2'
I/DEBUG ( 182): r0 00000000 r1 00004f71 r2 00000006 r3 00000000
I/DEBUG ( 182): r4 a0701db8 r5 00000006 r6 0000000b r7 0000010c
I/DEBUG ( 182): r8 00000000 r9 b486f520 sl a1c0ac00 fp 00000001
I/DEBUG ( 182): ip 00004f71 sp a07006d8 lr b6e503c5 pc b6e72f6c cpsr
60070010
I/DEBUG ( 182):
I/DEBUG ( 182): backtrace:
I/DEBUG ( 182): #00 pc 00039f6c /system/lib/libc.so (tgkill+12)
I/DEBUG ( 182): #01 pc 000173c1 /system/lib/libc.so (pthread_kill+52)
I/DEBUG ( 182): #02 pc 00017fd3 /system/lib/libc.so (raise+10)
I/DEBUG ( 182): #03 pc 00014795 /system/lib/libc.so (__libc_android_abor
t+36)
I/DEBUG ( 182): #04 pc 00012f44 /system/lib/libc.so (abort+4)
I/DEBUG ( 182): #05 pc 00228cd7 /system/lib/libart.so (art::Runtime::Abo
rt()+170)
I/DEBUG ( 182): #06 pc 000a7371 /system/lib/libart.so (art::LogMessage::
~LogMessage()+1360)
I/DEBUG ( 182): #07 pc 000b1b17 /system/lib/libart.so (art::JniAbort(cha
r const*, char const*)+1118)
I/DEBUG ( 182): #08 pc 000b2055 /system/lib/libart.so (art::JniAbortF(ch
ar const*, char const*, ...)+68)
I/DEBUG ( 182): #09 pc 000b530f /system/lib/libart.so (art::ScopedCheck:
:ScopedCheck(_JNIEnv*, int, char const*)+1346)
I/DEBUG ( 182): #10 pc 000b7755 /system/lib/libart.so (art::CheckJNI::Ge
tMethodID(_JNIEnv*, _jclass*, char const*, char const*)+36)
I/DEBUG ( 182): #11 pc 001332f7 /data/app/com.enterprisemobility.OCR-1/l
ib/arm/libtess.so (Java_com_googlecode_tesseract_android_TessBaseAPI_nativeClass
Init+46)
I/DEBUG ( 182): #12 pc 0000614d /data/dalvik-cache/arm/data@app@com.ente
rprisemobility.OCR-1@base.apk@classes.dex
W/ActivityManager( 536): Force finishing activity 1 com.enterprisemobility.OC
R/.MainActivity
I/DEBUG ( 182):
I/DEBUG ( 182): Tombstone written to: /data/tombstones/tombstone_07
Abort message比较清楚:你调用GetFieldID(cls, fieldName)
的字段名在你传给这个函数的class中不存在,但是您不检查该错误,而是继续调用其他 JNI 函数。不幸的是,您不能忽略此类错误。在调用 GetMethodID()
或 大多数 JNI 函数之前,您必须 调用ExceptionClear()
。
您可以使用 addr2line 查找对 getMethodID()
的具体调用崩溃,并据此推导出对 GetFieldID(cls, fieldName)
的调用失败。但我建议为所有 JNI 调用添加错误检查,因为明天其他函数可能会抛出异常。
很可能是您的 C++ 代码中错误地定义了 JNI 映射。 JNI 与 Java 在类型映射方面有非常严格的约定。例如, 在从 JNI 调用 Java 对象的方法之前,我们需要它的签名。所以方法:
long myMethod (int n, String s, int[] arr);
从具有签名的 JNI 中看到:
(ILJAVA/LANG/STRING;[I])J
您可以在此处阅读这些规则的非常全面的概述: http://www.rgagnon.com/javadetails/java-0286.html
你应该使用 android NDK 中的 ndk-stack 工具来找出崩溃的位置。查看 link 关于 ndk stack。
adb logcat > /tmp/foo.txt
$NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump foo.txt
我也有同样的问题,弄得我很困惑 2 days.Finally 原因是我传递了错误的对象 type.For 例子, java 代码是
public OverlayLine(int mWidth,List<GeoPoint> mPoints);
我注册了如下的jni方法:
gClass.mInitMethod = env->GetMethodID(gObject, "<init>", "(ILjava/lang/Object;)V");
并得到错误消息 Errol encounter.And 我修改了代码
gClass.mInitMethod = env->GetMethodID(gObject, "<init>", "(ILjava/util/List;)V");
和错误 gone.That 您应该传递精确的对象类型而不是 'Ljava/lang/Object;'。
调用 GetMethodID 时遇到类似问题:
JNI DETECTED ERROR IN APPLICATION: thread Thread[1,tid=15092,Runnable,Thread*=0x791c1b8000,peer=0x7278ab58,"main"] using JNI after critical get
... in call to GetMethodID
我使用 GetMethodID 之前调用了几次
inBufP = env->GetPrimitiveArrayCritical(jIn, NULL);
解法: 我可以通过将 GetPrimitiveArray 更改为 GetByteArrayElements
来修复本机崩溃jboolean isCopy;
inBufP = env->GetByteArrayElements(jIn, &isCopy);