参考源码版本:Android-4.4.4_r2
---------------------------------
dvmCreateJNIEnv函数创建一个JNIEnvExt结构,函数返回时,将JNIEnvExt*强制转换为JNIEnv*:
/* * 创建一个新的JNIEnvExt结构,并将它添加到VM列表中。 * 返回时,将JNIEnvExt*强制转换为JNIEnv*。 * Create a new JNIEnv struct and add it to the VM's list. * * "self"为NULL,表示这是主线程,因为VM还未启动。这个值在随后将被填充。 * "self" will be NULL for the main thread, since the VM hasn't started * yet; the value will be filled in later. */ JNIEnv* dvmCreateJNIEnv(Thread* self) { JavaVMExt* vm = (JavaVMExt*) gDvmJni.jniVm; //if (self != NULL) // ALOGI("Ent CreateJNIEnv: threadid=%d %p", self->threadId, self); assert(vm != NULL); JNIEnvExt* newEnv = (JNIEnvExt*) calloc(1, sizeof(JNIEnvExt)); newEnv->funcTable = &gNativeInterface; if (self != NULL) { dvmSetJniEnvThreadId((JNIEnv*) newEnv, self); assert(newEnv->envThreadId != 0); } else { /* make it obvious if we fail to initialize these later */ newEnv->envThreadId = 0x77777775; newEnv->self = (Thread*) 0x77777779; } if (gDvmJni.useCheckJni) { dvmUseCheckedJniEnv(newEnv); } ScopedPthreadMutexLock lock(&vm->envListLock); // 在JavaVMExt的JNIEnvExt列表(envList)的起始位置插入新的JNIEnvExt结构(newEnv)。 /* insert at head of list */ newEnv->next = vm->envList; assert(newEnv->prev == NULL); if (vm->envList == NULL) { // 罕见,但可能 // rare, but possible vm->envList = newEnv; } else { vm->envList->prev = newEnv; } vm->envList = newEnv; //if (self != NULL) // ALOGI("Xit CreateJNIEnv: threadid=%d %p", self->threadId, self); return (JNIEnv*) newEnv; }
全局变量gNativeInterface
在dalvik/vm/Jni.cpp
文件中。
JNIEnvExt结构:
struct JNIEnvExt { const struct JNINativeInterface* funcTable; /* must be first */ const struct JNINativeInterface* baseFuncTable; u4 envThreadId; Thread* self; /* if nonzero, we are in a "critical" JNI call */ int critical; struct JNIEnvExt* prev; struct JNIEnvExt* next; };
- funcTable中保存的是
&gNativeInterface
。 - envThreadId中保存绑定JNIEnvExt结构的线程的Id。
- self指向的是绑定JNIEnvExt的线程结构。
- prev中保存的是前一个JNIEnvExt结构的地址。如果当前节点是头节点,那么它的值是NULL。
- next中保存的是后一个JNIEnvExt结构的地址。如果当前节点是尾节点,那么它的值是NULL。
时间: 2024-10-12 20:03:25