参考源码版本: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。