3

所以如果我们附加我们必须在它完成后分离线程,对吧?

JNIEnv* get_jni_env()
{
JNIEnv* res;
JAVA_VM->GetEnv((void**) &res, JNI_VERSION_1_6);//Using cached JavaVM
JAVA_VM->AttachCurrentThread(&res, NULL);
return res;
}

我从我的 Activity 类的@Override protected void onDestroy()调用下一个本机方法

 void free_jni_manager()
 {
   JNIEnv* env = get_jni_env();
   ... //Here i delete global refs (jclass)
  //JAVA_VM->DetachCurrentThread();
 }

错误:使用 interp 帧(计数 = 16)分离线程- 主线程仍在运行,我们尝试分离它。

即使我们采用任何使用 JNIEnv 的函数(例如调用 java 方法),放置 DetachCurrentThread 也会导致相同的错误。

如果在pthread 函数中使用DetachCurrentThread可以完美工作

static void* thread_func(void* arg)
{
 get_jni_env(); // attach new thread
 //Do thread stuff
 JAVA_VM->DetachCurrentThread();//thread done detached it with ok
 return NULL;
}

我们是否需要分离主线程然后我们使用 JNI 完成,这样做吗?或者然后活动将被破坏,它会用JavaVM释放自己?我们是否需要调用 DestroyJavaVM()(如果使用 onDestroy 只会导致崩溃),免费缓存的 JavaVM 或垃圾清理器将如何处理这个问题?

PS 使用AttachCurrentThreadAsDaemon()有什么好处

4

2 回答 2

3

Activity.onDestroy()方法在 UI 线程上调用。为什么要尝试从 UI 线程中分离 Java VM?该线程由系统管理,您既不应该将 Java VM 附加到它,也不应该从它分离 Java VM。

JNIEnv*可用于每个本机方法作为第一个参数。为什么首先需要get_jni_env()

如果您需要工作线程上的 JNIEnv,那么您需要附加和分离(或从 Java 生成一个线程;这很容易)。

编辑:如果是重复附件,则无需分离。它不是一个引用计数系统。AttachCurrentThread记录为

尝试附加已附加的线程是无操作的。

而不是需要匹配的附加/分离调用。

于 2012-10-22T16:59:02.917 回答
1

不要JNI handler function从 main调用thread。从主线程调用JNI handler function会导致崩溃。

于 2016-04-12T12:53:30.977 回答