JNIEnvExt/JNIEnv创建过程分析

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

全局变量gNativeInterfacedalvik/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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值