如何防止 JNIEnv 超出线程范围?



当我尝试从C++线程调用JVM时,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'

有没有办法在没有 JNIEnv 或任何其他解决方案的情况下调用 JVM?

您可以将 jvm 指针缓存在JNI_OnLoad中,例如

JavaVM* g_jvm;
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
g_jvm = vm;
...
return result;
}

然后使用此g_jvm来执行AttachCurrentThreadDetachCurrentThread,例如

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

最新更新