[Java] [ Android ] [ JNI ] [ Native线程编程中使用JavaVM->AttachCurrentThread获取JNIEnv以访问Java层对象]

简介

由JVM的线程栈的设计,JNI编程必须遵守如下原则
• JNIEnv结构与线程绑定的,绝对不能在多线程中共享JNIEnv结构
• LocalRef与本线程绑定的,绝对不能在多线程中共享LocalRef

Native线程编程中使用JavaVM->AttachCurrentThread获取JNIEnv以访问Java层对象

A JNI interface pointer (JNIEnv*) is passed as an argument for each native
function mapped to a Java method, allowing for interaction
with the JNI environment within the native method.This JNI interface
pointer can be stored, but remains valid only in the current thread.
Other threads must first call AttachCurrentThread()to attach
themselves to the VM and obtain a JNI interface pointer. Once
attached, a native thread works like a regular Java thread running
within a native method. The native thread remains attached to the VM
until it callsDetachCurrentThread() to detach itself.[3]

因此,在Native线程中,需要通过JavaVM->AttachCurrentThread获取JNIEnv,再由JNIEnv去访问Java层类及对象。
JavaVM在Navtive中具有唯一实例,可通过全局变量保存

JavaVM *jvm; /* already set */
f()
{
  JNIEnv *env;
  (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  ... /* use env */
}

如上,只要jvm被赋值,就可通过AttachCurrentThread得到JNIEnv。
JavaVM结构可以在多线程间共享,有以下两个jvm的赋值时机:
• JNI_GetCreatedJavaVM创建虚拟机时
• JNI_OnLoad
此外,只要在该线程中事先调用过AttachCurrentThread后,JNIEnv->GetEnv可以返回JNIEnv。

你可能感兴趣的:([Java] [ Android ] [ JNI ] [ Native线程编程中使用JavaVM->AttachCurrentThread获取JNIEnv以访问Java层对象])