Так что, если мы присоединяем, мы должны отсоединить нить после того, как она закончится, верно?
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;
}
Я вызываю следующий нативный метод из @ Переопределить защищенный 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 ()
Activity.onDestroy()
метод вызывается в потоке пользовательского интерфейса. Почему вы пытаетесь отсоединить виртуальную машину Java от потока пользовательского интерфейса? Этот поток управляется системой, вы не должны ни присоединять, ни отсоединять виртуальную машину Java от нее.
JNIEnv*
доступно каждому нативному методу в качестве первого параметра. Зачем тебе get_jni_env()
на первом месте?
Если вам нужен JNIEnv в рабочих потоках, то вам нужно присоединять и отсоединять (ИЛИ порождать поток из Java; это довольно просто).
РЕДАКТИРОВАТЬ: Если это повторное вложение, вам не нужно отсоединяться. Это не система пересчета. AttachCurrentThread
задокументировано как
Попытка присоединить нить, которая уже присоединена, бесполезна.
В отличие от необходимости совмещенных вызовов присоединения / отключения.
Не звони JNI handler function
от основного thread
, призвание JNI handler function
из основного потока произойдет сбой.