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
Android JNI DETECTED ERROR IN APPLICATION: JNI GetMethodID called with pending exception
提问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
回答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;”。