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示例:

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

这是hello-jni.c添加的相关功能

  1. static JavaVM* jvm = 0;
  2. static jobject activity = 0; // GlobalRef
  3.  
  4. void* threadFunction(void* irrelevant)
  5. {
  6. JNIEnv* env;
  7. usleep(5000000);
  8.  
  9. __android_log_print(ANDROID_LOG_DEBUG,"threadFunction","Attaching");
  10.  
  11. (*jvm)->AttachCurrentThread(jvm,&env,NULL);
  12.  
  13. jclass clazz = (*env)->GetObjectClass(env,activity);
  14. jmethodID methodID = (*env)->GetMethodID(env,clazz,"finish","()V" );
  15. (*env)->CallVoidMethod(env,activity,methodID);
  16.  
  17. __android_log_print(ANDROID_LOG_DEBUG,"Not Detaching");
  18. // (*jvm)->DetachCurrentThread(jvm);
  19. }
  20.  
  21. jstring
  22. Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz )
  23. {
  24. (*env)->GetJavaVM(env,&jvm);
  25. activity = (*env)->NewGlobalRef(env,thiz);
  26.  
  27. pthread_t hThread;
  28. pthread_create(&hThread,NULL,&threadFunction,NULL);
  29. return (*env)->NewStringUTF(env,"Hello from JNI !");
  30. }

猜你在找的Android相关文章