在Android NDK中跨线程共享JavaVM*

Nee*_*raj 5 java-native-interface multithreading android-ndk

我想从一个接收来自另一个可执行文件的回调的cpp文件中调用Java类方法.

为此,我使用直接接收JNI方法调用的.cpp文件中的android :: AndroidRuntime :: getJavaVM()方法检索了一个JavaVM指针.我通过构造函数将此JavaVM指针共享到最终的.cpp文件,我在其中调用所需的Java方法,如下所示:

/* All the required objects(JNIEnv*,jclass,jmethodID,etc) are appropriately declared. */
**JNIEnv* env;
jvm->AttachCurrentThread(&env, NULL);
clazz = env->FindClass("com/skype/ref/NativeCodeCaller");
readFromAudioRecord = env->GetStaticMethodID(clazz, "readFromAudioRecord", "([B)I");
writeToAudioTrack = env->GetStaticMethodID(clazz, "writeToAudioTrack", "([B)I");** 
Run Code Online (Sandbox Code Playgroud)

但是,我遇到运行此代码的 SIGSEGV错误.

根据JNI文档,这似乎是在仲裁环境中获取JNIEnv的适当方式:http://java.sun.com/docs/books/jni/html/other.html#26206

在这方面的任何帮助将不胜感激.

此致,Neeraj

Jus*_*ser 2

如果您尝试使用 JNIEnv 或 JavaVM 引用而不将线程附加到 VM,则全局引用不会阻止新线程中的分段错误。你第一次做得正确, M\xc4\x81rti\xc5\x86\xc5\xa1 Mo\xc5\xbeeiko 错误地暗示你所做的事情有问题。

\n\n

不要删除它,只需学习如何使用它即可。那家伙不知道他在说什么,如果它在 jni.h 中,你可以很确定它不会去任何地方。它没有被记录下来的原因可能是因为它的不言自明是可笑的。您不需要创建 GlobalReference 对象或任何东西,只需执行以下操作:

\n\n
#include <jni.h>\n#include <string.h>\n#include <stdio.h>\n#include <android/log.h>\n#include <linux/threads.h>\n#include <pthread.h>\n\n#define  LOG_TAG    "[NDK]"\n#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)\n#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)\n#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)\n\nstatic pthread_mutex_t thread_mutex;\nstatic pthread_t thread;\nstatic JNIEnv* jniENV;\n\nvoid *threadLoop()\n{\n    int exiting;\n    JavaVM* jvm;\n    int gotVM = (*jniENV)->GetJavaVM(jniENV,&jvm);\n    LOGI("Got JVM: %s", (gotVM ? "false" : "true") );\n    jclass javaClass;\n    jmethodID javaMethodId;\n    int attached = (*jvm)->AttachCurrentThread(jvm, &jniENV,NULL);\n    if(attached>0)\n    {\n        LOGE("Failed to attach thread to JavaVM");\n        exiting = 1;\n    }\n    else{\n        javaClass= (*jniENV)->FindClass(jniENV, "com/justinbuser/nativecore/NativeThread");\n        javaMethodId= (*jniENV)->GetStaticMethodID(jniENV, javaClass, "javaMethodName", "()V");\n    }\n    while(!exiting)\n    {\n        pthread_mutex_lock(&thread_mutex);\n        (*jniENV)->CallStaticVoidMethod(jniENV, javaClass, javaMethodId);\n        pthread_mutex_unlock(&thread_mutex);\n    }\n    LOGE("Thread Loop Exiting");\n    void* retval;\n    pthread_exit(retval);\n    return retval;\n}\n\nvoid start_thread(){\n    if(thread < 1)\n        {\n            if(pthread_mutex_init(&thread_mutex, NULL) != 0)\n            {\n                LOGE( "Error initing mutex" );\n            }\n            if(pthread_create(&thread, NULL, threadLoop, NULL) == 0)\n            {\n                LOGI( "Started thread#: %d", thread);\n                if(pthread_detach(thread)!=0)\n                {\n                    LOGE( "Error detaching thread" );\n                }\n            }\n            else\n            {\n                LOGE( "Error starting thread" );\n            }\n        }\n}\n\nJNIEXPORT void JNICALL\nJava_com_justinbuser_nativecore_NativeMethods_startThread(JNIEnv * env, jobject this){\n    jniENV = env;\n    start_thread();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这是来自 NDK r8dplatforms\android-14\arch-arm\usr\include\jni.h 的 jni.h 文件:http://pastebin.com/04RgHUYN 请告诉我 `android` 和 `AndroidRuntime` 命名空间在哪里。 (2认同)