android Jni开发DetachCurrentThread使用报错 androidjniDetachCurrentThread 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我刚才也碰到这个问题。查了一些资料,得到的结论是在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来释放资源。 http://blog.csdn.net/birdsaction/article/details/17859395 我以前在JNI中使用过线程,不知道是否和你们用的一样。 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"); } 关于android 4.1「最近使用过应用程序」按钮的操作代码 求助,android 如何开启相机LED闪光灯 文字和按钮重叠了 新手求助 android中多个activity之间的跳转 android 源码裁剪 运行Android错误? 能不能启动一个service,然后马上跳转到另一个activity呢? 求最简单制作APP的方法(嵌入网站形式) android开发适配各种双卡手机真烦啊 WebView的loadUrl的网址中汉字问题 切换fragment时如何刷新fragment里的内容 qq空间评论功能的实现细节(android版qq)
查了一些资料,得到的结论是在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来释放资源。
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");
}