在JNI对话框生成器调用中出现空指针异常

Null Pointer Exception in alert Dialog Builder call from JNI

本文关键字:空指针异常 调用 JNI 对话框      更新时间:2023-10-16

我知道有很多关于它的问题,我已经看到了处理这类错误的帖子,但是我在一个特殊的JNI调用竞赛中。Android JNI -调用AttachCurrentThread而不调用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);警报。setTitle("新技术");警报。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函数不在uthread上,这就是为什么我得到一个错误。但我不确定这就是问题所在,我也不知道如何解决这个问题。你们有人知道我能做什么吗?

编辑:所以我试着删除与AlertDialog处理的所有代码,问题不会发生。所以它似乎要么是一个问题与线程或问题与AlertDialog…但我猜这更像是一个线程问题,因为在这个函数之外创建一个简单的AlertDialog。

您的NewObject呼叫有问题。

传递给NewObject的第二个参数应该是对构造函数的引用,但在您的情况下,它与CallVoidMethod调用的方法相同。

构造一个新的Java对象。方法ID指示要调用的构造函数方法。此ID必须通过使用调用GetMethodID()来获得。作为方法名,void (V)作为返回类型

你没有显示你初始化javaMethodRef的代码,所以不清楚它是构造函数还是另一个方法。如果它是构造函数,您只需要调用它一次,并且CallVoidMethod调用是多余的。如果它不是构造函数,则应该调用构造函数。您可以使用类似于以下代码的引用:

jmethodID constructor = env->GetMethodID(javaClassRef, "<init>", "()V");
jobject javaObjectRef = env->NewObject(javaClassRef, constructor);

如果构造函数有参数,将它们的类型添加到签名中,并在constructor之后传递给NewObject