Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/219.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android:CallStaticVoidMethod只被调用一次_Java_Android_Java Native Interface - Fatal编程技术网

Java Android:CallStaticVoidMethod只被调用一次

Java Android:CallStaticVoidMethod只被调用一次,java,android,java-native-interface,Java,Android,Java Native Interface,我有一个JNI代码,我试图在Java中调用一个静态方法 JNI中的OnLoad如下所示 extern "C" jint JNI_OnLoad(JavaVM *jvm, void *reserved) { JNIEnv *e; mJvm = jvm; if (jvm->GetEnv((void**) &e, JNI_VERSION_1_4) != JNI_OK) { ALOGE("Error gett

我有一个JNI代码,我试图在Java中调用一个静态方法

JNI中的OnLoad如下所示

extern "C" jint JNI_OnLoad(JavaVM *jvm, void *reserved) {
        JNIEnv *e;

        mJvm = jvm;

        if (jvm->GetEnv((void**) &e, JNI_VERSION_1_4) != JNI_OK) {
                ALOGE("Error getting Env var");
                return JNI_ERR;
        }

        ALOG_ASSERT(env, "Could not retrieve the env!");

        app = e->FindClass("xyz");
        updateService = e->GetStaticMethodID(app, "updatestatus", "(I)V");

        jniRegisterNativeMethods(e, "xyz",
                                 Methods, NELEM(Methods));

        return JNI_VERSION_1_4;
}
我有以下全局变量

JavaVM *mJvm;
jclass app;
jmethodID updateHDToService;
我试图调用Java方法的回调如下所示

JNIEnv *e;
if (!mIsListenerAttached) {
        if (mJvm->AttachCurrentThread(&e, NULL) != JNI_OK) {
                ALOGE("Error attaching native thread to java");
                mIsListenerAttached = false;
                return;
        }
        ALOGI("Aattached native thread to java");
        mIsListenerAttached = true;
}

e->CallStaticVoidMethod(app, updateHDToService, radioContext->signalStat);
Java中的静态方法只成功调用了一次。下次执行相同的回调时,它不会调用java方法

我做错了什么?

请看一下。您不需要保护变量


但是不要忘记在本机线程退出之前调用
mJvm->detachCurrentThread()

显然,有一个类的成员
bool mIsListenerAttached
。您的代码期望每个(本机)线程都有一个该成员的实例。但是,如果要从一个本机线程多次调用
xyz.uodatestatus()
Javavoid方法,则可能需要将
mIsListenerAttached
保存在线程本地存储(也称为TLS)中,或者使用替代机制。在本机线程退出之前,不要忘记调用
mJvm->detachCurrentThread()
。@AlexCohn我在JNI文件中将
bool作为全局变量错误地附加了
。我的JNI没有任何课程。这本身可能是个问题,不确定。我是JNI的新手。如何确定是否有多个本机线程?如果一个线程是,它将运行所谓的“线程函数”。最后,它要么调用,要么简单地返回。这是线程生命的结束。如果线程被附加到JVM,那么在以上述任一方式完成之前,它应该被显式分离。实际上,您可以在调用Java回调后立即分离线程,但是如果这种情况太频繁,那么开销可能会很大。我没有明确地开始任何线程。我正在构建一个JNI库,并将该库加载到应用程序的Java代码中。我的印象是,您使用一个大的第三方库作为黑盒,它可能会启动自己的线程。如果不是这样,并且所有执行路径都从Java应用程序开始,那么您可能会忘记所有这些
AttachCurrentThread()
DetachCurrentThread()
。我使用的是第三个部分库,它在调用线程的API时创建线程。我试图调用Java方法的地方是在我向第三方API注册的回调中。在这种情况下,我应该在哪里分离线程?正如我所建议的,您可以在调用Java回调后立即分离线程。如果这种情况发生得太频繁,开销可能会很大。解释如何注册在pthread被销毁时自动执行的函数。