Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Android jvm->GetEnv() return the same "env" for multiple threads.?

I'm using jvm->GetEnv(&envThread, JNI_VERSION_1_6) to get the "env" for multple threads in order to make multiple envThread->GetMethodID() calls. Both threads are properly attached to the JVM.

I call the function returned by "GetMethodID()" on the first thread with no problems, but when the second thread attemps the call I see this message:

art/runtime/check_jni.cc:65] JNI DETECTED ERROR IN APPLICATION: thread Thread[13,tid=8207,Native,Thread*=0xaed08400,peer=0x12dcd080,"Thread-10224"]
  using JNIEnv* from thread Thread[1,tid=8148,Runnable,Thread*=0xb4e07800,peer=0x87bc5ef0,"main"]

A/art(8148): art/runtime/check_jni.cc:65 in call to CallVoidMethodV
08-31 14:11:08.029: A/art(8148): art/runtime/check_jni.cc:65] "Thread-10224" prio=10 tid=13 Runnable
08-31 14:11:08.029: A/art(8148): art/runtime/check_jni.cc:65] group="main" sCount=0 dsCount=0 obj=0x12dcd080 self=0xaed08400
08-31 14:11:08.029: A/art(8148): art/runtime/check_jni.cc:65] sysTid=8207 nice=-11 cgrp=apps sched=0/0 handle=0xafb18b00
08-31 14:11:08.029: A/art(8148): art/runtime/check_jni.cc:65] state=R schedstat=( 17710887 6014947 64 ) utm=1 stm=0 core=3 HZ=100
08-31 14:11:08.029: A/art(8148): art/runtime/check_jni.cc:65]   | stack=0xaee04000-0xaee06000 stackSize=1012KB

Because my call to jvm->getEnv() returns JNI_OK for the second thread, it is already attached (as expected). But what isn't expected is that the JniENV returned is exactly the same as the one from the first thread. Thus causing the crash.

Has anyone seen this sort of thing before? I'm quite lost for what to do...

Thanks.

like image 279
Bungles Avatar asked Oct 20 '25 14:10

Bungles


1 Answers

I think you should be using AttachCurrentThread from the other thread.

Here's a similar question on SO:

void callback(int val) {
    JNIEnv * g_env;
    // double check it's all ok
    int getEnvStat = g_vm->GetEnv((void **)&g_env, JNI_VERSION_1_6);
    if (getEnvStat == JNI_EDETACHED) {
        std::cout << "GetEnv: not attached" << std::endl;
        if (g_vm->AttachCurrentThread((void **) &g_env, NULL) != 0) {
            std::cout << "Failed to attach" << std::endl;
        }
    } else if (getEnvStat == JNI_OK) {
        //
    } else if (getEnvStat == JNI_EVERSION) {
        std::cout << "GetEnv: version not supported" << std::endl;
    }

    g_env->CallVoidMethod(g_obj, g_mid, val);

    if (g_env->ExceptionCheck()) {
        g_env->ExceptionDescribe();
    }

    g_vm->DetachCurrentThread();
}
like image 87
Buddy Avatar answered Oct 23 '25 04:10

Buddy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!