【问题标题】:NDK app onDestroy cleanup - how to DetachCurrentThreadNDK 应用程序 onDestroy 清理 - 如何 DetachCurrentThread
【发布时间】:2012-10-22 11:58:22
【问题描述】:

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

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 帧 (count=16) 分离线程 - 主线程仍在运行,我们尝试将其分离。

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

DetachCurrentThread 如果在 pthread 函数

中使用,则可以完美运行
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 或垃圾清理器将如何处理这个问题?

附:使用 AttachCurrentThreadAsDaemon()

有什么好处

【问题讨论】:

    标签: android c++ android-ndk java-native-interface


    【解决方案1】:

    在 UI 线程上调用 Activity.onDestroy() 方法。为什么要尝试从 UI 线程中分离 Java VM?该线程由系统管理,您不应将 Java VM 与其连接或分离。

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

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

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

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

    与要求匹配的附加/分离调用相反。

    【讨论】:

    • 是的,JNIEnv 是本地 java 方法中的参数是正确的(例如从 Java 代码调用 C/C++),但是如果我们需要做相反的事情(例如从 C\C++ 代码调用 Java 方法),我们需要get_jni_env().
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-18
      • 2021-08-28
      • 2014-10-26
      • 2011-10-09
      • 2022-06-14
      • 1970-01-01
      • 2016-05-01
      相关资源
      最近更新 更多