Как удержать JNIEnv от выхода из области видимости в потоке? - PullRequest
1 голос
/ 06 октября 2019

Когда я пытаюсь вызвать JVM из потока в C ++, debbuger говорит, что указатель JNIEnv пропал. Код:

void thread_call(JNIEnv* env,jobject text_view,jmethodID setText,const char* str){
    env->CallVoidMethod(text_view,setText,env->NewStringUTF(str));
}

JNIEXPORT jstring JNICALL
Java_com_example_project_1lenspath_MainActivity_initPullThread(
        JNIEnv *env,
        jobject, jobject text_view){
     ...
     std::thread pull(thread_call,env,text_view,setText,std::to_string(t).c_str());
     ...
}
//Debugger:
error: use of undeclared identifier 'env'

Есть ли способы вызвать JVM без JNIEnv или другого решения?

1 Ответ

2 голосов
/ 07 октября 2019

Вы можете кэшировать указатель jvm внутри JNI_OnLoad, например,

JavaVM* g_jvm;

jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    g_jvm = vm;

    ...
    return result;
}

Затем используйте это g_jvm, чтобы сделать AttachCurrentThread и DetachCurrentThread, например,

void foo() 
{
    jint res = javaVM->GetEnv((void**)&env, JNI_VERSION_1_6);
    if (res != JNI_OK) {
        res = javaVM->AttachCurrentThread(&env, NULL);
        if (JNI_OK != res) {
            return NULL;
        }
    }

    ...

    g_jvm->DetachCurrentThread();
}

См .: https://github.com/russell-shizhen/JniExample/blob/master/app/src/main/cpp/native-lib.cpp

...