Android JNI - 调用AttachCurrentThread而不使用DetachCurrentThread

采得百花成蜜后,为谁辛苦为谁甜。这篇文章主要讲述Android JNI - 调用AttachCurrentThread而不使用DetachCurrentThread相关的知识,希望能为你提供帮助。
我一直在阅读关于JNI的东西,似乎无法弄清楚如果线程启动会发生什么 - > 调用AttachCurrentThread() - > 进行一些JNI调用 - > 线程退出。
理想情况下,我们应该在线程退出之前调用DetachCurrentThread(),但是,如果应用程序不这样做会有什么影响?它会导致内存泄漏或任何其他问题吗?
答案不调用DetachCurrentThread()肯定会导致内存泄漏; 其他后果是JVM特有的,和 可能与android应用无关,其中JVM在进程退出时关闭 。有很多C ++包装器可以帮助管理线程Attach / Detach,例如参见:http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier
更新:1000感谢fadden的开眼界link; 在Dalvik上,一个不调用DetachCurrentThread()而退出的线程,会导致整个虚拟机和进程崩溃。
这是来自官方模拟器的logcat,我的代码基于来自NDK的HelloJni样本:

10-26 04:16:25.853: D/dalvikvm(1554): Trying to load lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0 10-26 04:16:25.893: D/dalvikvm(1554): Added shared lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0 10-26 04:16:25.893: D/dalvikvm(1554): No JNI_OnLoad found in /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0, skipping init 10-26 04:16:26.463: D/gralloc_goldfish(1554): Emulator without GPU emulation detected. 10-26 04:16:31.033: D/threadFunction(1554): Attaching 10-26 04:16:31.173: D/threadFunction(1554): Not Detaching 10-26 04:16:31.183: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=0) 10-26 04:16:31.193: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=1) 10-26 04:16:31.193: E/dalvikvm(1554): threadid=11: native thread exited without detaching 10-26 04:16:31.193: E/dalvikvm(1554): VM aborting 10-26 04:16:31.213: A/libc(1554): Fatal signal 6 (SIGABRT) at 0x00000612 (code=-6), thread 1567 (xample.hellojni)

以下是添加到hello-jni.c的相关功能:
static javaVM* jvm = 0; static jobject activity = 0; // GlobalRefvoid* threadFunction(void* irrelevant) { JNIEnv* env; usleep(5000000); __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Attaching"); (*jvm)-> AttachCurrentThread(jvm, & env, NULL); jclass clazz = (*env)-> GetObjectClass(env, activity); jmethodID methodID = (*env)-> GetMethodID(env, clazz, "finish", "()V" ); (*env)-> CallVoidMethod(env, activity, methodID); __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Not Detaching"); //(*jvm)-> DetachCurrentThread(jvm); }jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz ) { (*env)-> GetJavaVM(env, & jvm); activity = (*env)-> NewGlobalRef(env, thiz); pthread_t hThread; pthread_create(& hThread, NULL, & threadFunction, NULL); return (*env)-> NewStringUTF(env, "Hello from JNI !"); }

【Android JNI - 调用AttachCurrentThread而不使用DetachCurrentThread】在WebRTC git repo中可以找到这种策略的一个很好的实现。

    推荐阅读