解决方案 »

  1.   

    我刚才也碰到这个问题。
    查了一些资料,得到的结论是在java线程中不能使用AttachCurrentThread、DetachCurrentThread方法来获取JNIEnv。
    估计你调用DetachCurrentThread函数的地方在java线程中,即在java调用C++代码时在C++代码中调用了AttachCurrentThread方法来获取JNIEnv,此时JNIEnv已经通过参数传递进来,你不需要再次AttachCurrentThread来获取。在释放时就会报错。
    我使用的方法是通过下面的函数来获取JNIEnv,还没有严格经过验证,仅供参考。
    typedef enum _GET_JNIENV_STATUS{
    GET_FAIL = 0,
    GET_SUCCES_NOATTACH,
    GET_SUCCES_ATTCH,
    }Get_JNIEnv_Status;
    static Get_JNIEnv_Status getJNIEnv(JNIEnv *env)
    {
    Get_JNIEnv_Status GetStatus = GET_FAIL;  
        int status = myVm->GetEnv((void **) &env, JNI_VERSION_1_4);  
      
        if(status < 0) {  
            LOGD("callback_handler:failed to get JNI environment assuming native thread");   
            status = myVm->AttachCurrentThread(&env, NULL);  
            if(status < 0) {  
               LOGE("callback_handler: failed to attach current thread");  
                return GetStatus;  
            }  
            GetStatus = GET_SUCCES_ATTCH;  
        }
    else
    {
    GetStatus = GET_SUCCES_NOATTACH;
    }
    return GetStatus;
    }当返回值为GET_SUCCES_ATTCH时,需要调用DetachCurrentThread来释放资源。
      

  2.   

    http://blog.csdn.net/birdsaction/article/details/17859395 我以前在JNI中使用过线程,不知道是否和你们用的一样。
      

  3.   


    void *run_task(void *args) { //线程需要执行的东西  
        JNIEnv* env = NULL;  
          
        int n = (*jvm1)->AttachCurrentThread(jvm1,&env, NULL); //从jvm中获取到JNIEnv  
        if (n == 0) {  
              
            jstring msg = (*env)->NewStringUTF(env,"Yes Thread Running.");  
            (*env)->CallVoidMethod(env, obj1, mid1, msg); //回调JAVA层Callback类中的方法  
            (*env)->DeleteGlobalRef(env,obj1); //删除引用  
            (*jvm1)->DetachCurrentThread(jvm1); //这个一定要调用,否则报错,意在取消线程与jvm关联  
        }  
        LOGI("44");  
    }