应用程序中的Android JNI DETECTED ERROR:JNI GetMethodID被调用挂起exception

我正在尝试用我的android项目运行Googles OCR Tesseract。 我已经用android-ndk编写了tesseract,并在我尝试运行android项目后收到此错误。

我的环境如下

  • Android 5.1.1
  • android-ndk-r10e for windows
  • Android的SDK-R22

作为参考,我是根据此处列出的示例链接示例构建的

提前致谢!

这是我的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 

中止消息相对清楚:您为传递给此函数的类中不存在的字段名称调用GetFieldID(cls, fieldName) ,但不检查该错误,并继续调用其他JNI函数。 不幸的是,你不能忽视这些错误。 您必须在调用GetMethodID()大多数 JNI函数之前调用ExceptionClear()

您可以使用addr2line查找对getMethodID()崩溃的特定调用,并基于此,派生对GetFieldID(cls, fieldName)调用失败。 但我建议将错误检查添加到所有JNI调用,因为明天其他一些函数可能会抛出exception。

我有同样的问题,它让我迷惑了2天。最后的原因是我传递了错误的对象类型。例如,java代码是

 public OverlayLine(int mWidth,List mPoints); 

我注册jni方法如下:

 gClass.mInitMethod = env->GetMethodID(gObject, "", "(ILjava/lang/Object;)V"); 

并获取错误消息作为Errol遇到。我修复了代码

 gClass.mInitMethod = env->GetMethodID(gObject, "", "(ILjava/util/List;)V"); 

并且错误消失了。你应该传递精确的对象类型而不是’Ljava / lang / Object;’。

你应该在android NDK中使用ndk-stack工具找出崩溃的位置。 看到有关ndk堆栈的链接。

 adb logcat > /tmp/foo.txt $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump foo.txt 

很可能JNI映射在C ++代码中定义不正确。 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