【发布时间】:2016-08-16 17:26:28
【问题描述】:
我知道有人问过很多关于它的问题,而且我已经看过这篇处理此类错误的帖子,但我正在参加 JNI 调用的特殊竞赛。 Android JNI - Call AttachCurrentThread without DetachCurrentThread
所以这就是我要做的: 我有一个单独的 c++ 线程运行一些代码,并且在某些时候(在计时器结束后)我需要在 java 中调用一个回调函数。该回调函数用于显示一些警报,然后运行一些代码。
所以基本上这里是我的代码 c++ 方面:
JNIEXPORT void JNICALL package_endTrialJava(){
LOGD("EndTrialJava");
JNIEnv* env;
int getEnvStat = g_jvm->GetEnv((void **)&env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
LOGD("GetEnv: not attached");
//if (g_jvm->AttachCurrentThread((void **) &env, NULL) != 0) {
if (g_jvm->AttachCurrentThread(&env, NULL) != 0) {
LOGD("Failed to attach");
}
else{
jobject javaObjectRef = env->NewObject(javaClassRef, javaMethodRef);
env->CallVoidMethod(javaObjectRef, javaMethodRef);
}
} else if (getEnvStat == JNI_OK) {
//
} else if (getEnvStat == JNI_EVERSION) {
LOGD("GetEnv: version not supported");
}
//See https://stackoverflow.com/questions/26534304/android-jni-call-attachcurrentthread-without-detachcurrentthread
g_jvm->DetachCurrentThread();
}
然后在 Java 端调用的函数执行以下操作: AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this); alert.setTitle("下一个技术"); alert.setMessage("你现在将尝试另一种技术");
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
alertBeforeTrial();
return ;
}
});
AlertDialog alertdialog = alert.create();
alertdialog.show();
但是我得到以下错误:
W/art (24708): Thread[20,tid=24780,Native,Thread*=0x4e1ab1c8,peer=0x649247a0,"Thread-1128"] attached without supplying a name
D/TEST (24708): End Trial
F/art (24708): art/runtime/check_jni.cc:64] JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception 'java.lang.NullPointerException' thrown in unknown throw location
F/art (24708): art/runtime/check_jni.cc:64] in call to CallVoidMethodV
F/art (24708): art/runtime/check_jni.cc:64] "Thread-1128" prio=5 tid=20 Runnable
F/art (24708): art/runtime/check_jni.cc:64] | group="main" sCount=0 dsCount=0 obj=0x649247a0 self=0x4e1ab1c8
F/art (24708): art/runtime/check_jni.cc:64] | sysTid=24780 nice=0 cgrp=apps sched=0/0 handle=0x493da480
F/art (24708): art/runtime/check_jni.cc:64] | state=R schedstat=( 282584 1729083 7 ) utm=0 stm=0 core=3 HZ=100
F/art (24708): art/runtime/check_jni.cc:64] | stack=0x4e9cf000-0x4e9d3000 stackSize=1016KB
F/art (24708): art/runtime/check_jni.cc:64] (no managed stack frames)
F/art (24708): art/runtime/check_jni.cc:64]
F/art (24708): art/runtime/runtime.cc:203] Runtime aborting...
F/art (24708): art/runtime/runtime.cc:203] Aborting thread:
F/art (24708): art/runtime/runtime.cc:203] "Thread-1128" prio=5 tid=20 Runnable
F/art (24708): art/runtime/runtime.cc:203] | group="main" sCount=0 dsCount=0 obj=0x649247a0 self=0x4e1ab1c8
F/art (24708): art/runtime/runtime.cc:203] | sysTid=24780 nice=0 cgrp=apps sched=0/0 handle=0x493da480
F/art (24708): art/runtime/runtime.cc:203] | state=R schedstat=( 1254668 1729083 7 ) utm=0 stm=0 core=3 HZ=100
F/art (24708): art/runtime/runtime.cc:203] | stack=0x4e9cf000-0x4e9d3000 stackSize=1016KB
F/art (24708): art/runtime/runtime.cc:203] native: art::Thread::DumpStack(std::ostream&) const+87 [0x41709b78] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: ??? [0x41701c62] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: art::Runtime::Abort()+79 [0x41702204] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: art::LogMessage::~LogMessage()+507 [0x415ad89c] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: ??? [0x415b5ad4] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: art::JniAbortF(char const*, char const*, ...)+51 [0x415b6254] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: ??? [0x415b817c] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: ??? [0x415b83e6] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: ??? [0x415befe6] (libart.so)
F/art (24708): art/runtime/runtime.cc:203] native: _JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, ...)+40 [0x48c8ac68] (libnative.so)
F/art (24708): art/runtime/runtime.cc:203] native: package_endTrialJava+268 [0x48c8f8f0] (libnative.so)
F/art (24708): art/runtime/runtime.cc:203] native: FluidMechanics::Impl::endTrial()+772 [0x48c8fc20] (libnative.so)
F/art (24708): art/runtime/runtime.cc:203] native: std::thread::_Impl<std::_Bind_simple<std::_Mem_fn<void (FluidMechanics::Impl::*)()> (FluidMechanics::Impl*)> >::_M_run()+36 [0x48c8a128] (libnative.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] native: execute_native_thread_routine+11 [0x47f2c53c] (libgnustl_shared.so)
F/art (24708): art/runtime/runtime.cc:203] (no managed stack frames)
F/art (24708): art/runtime/runtime.cc:203] Pending exception java.lang.NullPointerException thrown by 'unknown throw location'
F/art (24708): art/runtime/runtime.cc:203] java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
F/art (24708): art/runtime/runtime.cc:203] at android.content.pm.ApplicationInfo android.content.ContextWrapper.getApplicationInfo() (ContextWrapper.java:152)
F/art (24708): art/runtime/runtime.cc:203] at android.content.res.Resources$Theme android.view.ContextThemeWrapper.getTheme() (ContextThemeWrapper.java:103)
F/art (24708): art/runtime/runtime.cc:203] at int android.app.AlertDialog.resolveDialogTheme(android.content.Context, int) (AlertDialog.java:143)
F/art (24708): art/runtime/runtime.cc:203] at void android.app.AlertDialog$Builder.<init>(android.content.Context) (AlertDialog.java:360)
F/art (24708): art/runtime/runtime.cc:203] at void fr.limsi.ARViewer.MainActivity.alertBeforeNewTechnique() (MainActivity.java:329)
F/art (24708): art/runtime/runtime.cc:203] at void fr.limsi.ARViewer.MainActivity.showAlerts() (MainActivity.java:320)
F/art (24708): art/runtime/runtime.cc:203] at void fr.limsi.ARViewer.MainActivity.endTrial() (MainActivity.java:369)
F/art (24708): art/runtime/runtime.cc:203] Dumping all threads without appropriate locks held: thread list lock mutator lock
F/art (24708): art/runtime/runtime.cc:203] All threads:
F/art (24708): art/runtime/runtime.cc:203] DALVIK THREADS (20):
F/art (24708): art/runtime/runtime.cc:203] "main" prio=5 tid=1 Native
F/art (24708): art/runtime/runtime.cc:203] | group="main" sCount=0 dsCount=0 obj=0x646c7b70 self=0x41da3c80
F/art (24708): art/runtime/runtime.cc:203] | sysTid=24708 nice=0 cgrp=apps sched=0/0 handle=0x4010b154
F/art (24708): art/runtime/runtime.cc:203] | state=S schedstat=( 2797045067 1500623419 9968 ) utm=213 stm=66 core=0 HZ=100
F/art (24708): art/runtime/runtime.cc:203] | stack=0xbe552000-0xbe556000 stackSize=8MB
F/art (24708): art/runtime/runtime.cc:203] native: android::Looper::pollOnce(int, int*, int*, void**)+92 [0x401ab94d] (libutils.so)
F/art (24708): art/runtime/runtime.cc:203] native: android::NativeMessageQueue::pollOnce(_JNIEnv*, int)+22 [0x40254331] (libandroid_runtime.so)
F/art (24708): art/runtime/runtime.cc:203] native: oatexec+18045636 [0x634efac4] (system@framework@boot.oat)
F/art (24708): art/runtime/runtime.cc:203] at android.os.MessageQueue.nativePollOnce(Native method)
F/art (24708): art/runtime/runtime.cc:203] at android.os.MessageQueue.next(MessageQueue.java:138)
F/art (24708): art/runtime/runtime.cc:203] at android.os.Looper.loop(Looper.java:123)
F/art (24708): art/runtime/runtime.cc:203] at android.app.ActivityThread.main(ActivityThread.java:5030)
F/art (24708): art/runtime/runtime.cc:203] at java.lang.reflect.Method.invoke(Native method)
F/art (24708): art/runtime/runtime.cc:203] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
F/art (24708): art/runtime/runtime.cc:203] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
我的一个有根据的猜测是,这与UIThread 有关。我想我在 c++ 中的线程对 java 函数的调用不在 UIThread 上,这就是我收到错误的原因。但我不确定这实际上是问题所在,我不知道如何解决这个问题。你们有人知道我能做什么吗?
编辑:所以我尝试删除所有处理 AlertDialog 的代码并且问题没有发生。所以看起来要么是 UIThread 的问题,要么是 AlertDialog 的问题......但我猜这更像是一个 UIThread 问题,因为在这个函数之外创建一个简单的 AlertDialog 是可行的。
【问题讨论】:
-
您认为问题可能是 ThreadUI 问题:您可以尝试在 Java 中使用一个虚拟方法(一次在正确的线程中,一次不在正确的线程中)来检查是否您在没有 JNI 的情况下复制了该问题。它不会解决问题,但可能会限制要调查的潜在问题的数量。
-
@callmeSteve 所以我尝试删除所有处理 AlertDialog 的代码并且问题没有发生。因此,这似乎是 UIThread 的问题或 AlertDialog 的问题......但我猜这更像是一个 UIThread 问题,因为在此函数之外创建一个简单的 AlertDialog 有效。
-
所以您自己创建了一个新的活动实例,然后在其上调用一个方法?那是行不通的 - 活动不会针对您想要活动的任何内容进行初始化,例如对话框的活动上下文。
-
@laalto 不确定我明白你的意思,但我自己并没有创建新的活动实例。我使用的 MainActivity 是使用 onCreate 方法创建的。它调用了一些本地 c++ 函数,这些函数必须调用 Java 中的回调函数。这就是我上面提到的问题
-
堆栈跟踪是关于传递给
AlertDialog.Builder的无效上下文(从非 UI 线程调用的对话框稍后会为您提供不同的堆栈跟踪)。 JNI sn-p 不完整,但NewObject对我来说是可疑的。
标签: java android c++ java-native-interface