Java 应用程序中的 Android JNI 检测到错误:JNI GetMethodID 调用时出现未决异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34891686/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:05:37  来源:igfitidea点击:

Android JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception

javaandroidandroid-ndkjava-native-interfacetesseract

提问by Errol Green

I'm trying to run a Googles OCR Tesseract with my android project. I have already complied tesseract with android-ndk and am receiving this error after I try and run the android project.

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

My environment is as follows

我的环境如下

  • Android 5.1.1
  • android-ndk-r10e for windows
  • android-sdk-r22
  • 安卓 5.1.1
  • 适用于 Windows 的 android-ndk-r10e
  • android-sdk-r22

For reference, I'm building from an example that is listed here Example Link

作为参考,我正在从此处列出的示例构建示例链接

Thanks in advance!

提前致谢!

Here is a snippet of my logcat result:

这是我的 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@[email protected]
    [email protected]@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

采纳答案by Alex Cohn

The Abort messageis relatively clear: you call GetFieldID(cls, fieldName)for a field name that does not exist in the class you pass to this function, but you don't check for that error, and continue to call other JNI functions. Unfortunately, you cannot ignore such errors. You mustcall ExceptionClear()before calling GetMethodID()or mostof the JNI functions.

中止的消息是比较明确的:你叫GetFieldID(cls, fieldName)为不传递给这个函数的类存在的字段名,但你没有检查这个错误,并继续调用其他JNI功能。不幸的是,您不能忽略此类错误。你必须调用ExceptionClear()之前调用GetMethodID()大部分的JNI功能。

You can use addr2lineto find which specific call to getMethodID()crashed, and based on this, derive which call to GetFieldID(cls, fieldName)failed. But I would advise to add error checking to all your JNI calls, because tomorrow some other function may throw an exception.

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

回答by IgorGanapolsky

Most likely the JNI mappings were incorrectly defined in your C++ code. JNI has very strict contracts about type mappings with Java. For example, before calling a Java object's method from JNI, we need its signature. So the method:

很可能 JNI 映射在您的 C++ 代码中定义不正确。JNI 与 Java 的类型映射有非常严格的约定。例如,在从 JNI 调用 Java 对象的方法之前,我们需要它的签名。所以方法:

long myMethod (int n, String s, int[] arr);

long myMethod (int n, String s, int[] arr);

is seen from JNI with the signature:

从带有签名的 JNI 中可以看到:

(ILJAVA/LANG/STRING;[I])J

(ILJAVA/LANG/STRING;[I])J

You can read a very comprehensive overview of these rules here: http://www.rgagnon.com/javadetails/java-0286.html

您可以在此处阅读有关这些规则的非常全面的概述:http: //www.rgagnon.com/javadetails/java-0286.html

回答by HungNM2

you should use ndk-stack tool in android NDK to find out the crashed position. see the link about ndk stack.

您应该使用 android NDK 中的 ndk-stack 工具找出崩溃的位置。请参阅有关ndk 堆栈的链接。

adb logcat > /tmp/foo.txt

$NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump foo.txt

回答by choufucai

I have the same problem,and it confuse me 2 days.Finally the reason is that I pass the wrong object type.For example, the java code is

我也有同样的问题,困惑了2天。最后是我传错了对象类型,比如java代码是

public OverlayLine(int mWidth,List<GeoPoint> mPoints);

and I register jni method as below:

我注册 jni 方法如下:

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

and gets the error message as Errol encounter.And I fix the code

并在遇到 Errol 时收到错误消息。我修复了代码

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

and the error gone.That you should pass the precise object type rather than 'Ljava/lang/Object;'.

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