【Android-系统】JNIEnv定义在哪

libnativehelper/include_jni/jni.h中

JNIEnv是什么?

#if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
#endif
  • 如果用C++编译器,那么JNIEnv就是_JNIEnv
  • 如果用C编译器,那么JNIEnv就是JNIInvokeInterface

_JNIEnv是什么呢?

请看:

struct _JNIEnv {
    const struct JNINativeInterface* functions;
#if defined(__cplusplus)
    jint GetVersion()
    { return functions->GetVersion(this); }
    jclass DefineClass(const char *name, jobject loader, const jbyte* buf, jsize bufLen)
    { return functions->DefineClass(this, name, loader, buf, bufLen); }
    
    ...
#endif
}
  • _JNIEnv是一个结构体
  • 它有一个JNINativeInterface成员
  • _JNIEnv所有的接口调用实际上都是转手交给了JNINativeInterface

由此可见,无论是C还是C++,JNIEnv本质上都是JNINativeInterface

JNINativeInterface是什么?

答:接口函数指针表

/*
 * Table of interface function pointers.
 */
struct JNINativeInterface {
    //预留了四个指针
    void*       reserved0;  
    void*       reserved1;
    void*       reserved2;
    void*       reserved3;
    
    //接口函数指针:
    jint        (*GetVersion)(JNIEnv *);

    jclass      (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, jsize);
    
    jclass      (*FindClass)(JNIEnv*, const char*);

    jmethodID   (*FromReflectedMethod)(JNIEnv*, jobject);
    jfieldID    (*FromReflectedField)(JNIEnv*, jobject);

	...(省略300多行)
  • 大约230个函数指针(Android8.1)

JNIEnv是在哪里创建的?

从Zygote的启动入口函数开始:

//frameworks\base\cmds\app_process\app_main.cpp
int main(int argc, char* const argv[]){
	...
	runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}

//
void AndroidRuntime::start(const char* className,...){
	...
	//初始化jni_invocation,实际上是导入libart.so库,
	//然后找到创建虚拟机的函数并把地赋给JNI_CreateJavaVM_
	//后面将调用这个函数
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动虚拟机:其实是调用JNI_CreateJavaVM_
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);
}

//libnativehelper\JniInvocation.cpp
bool JniInvocation::Init(const char* library) {
  ...
  if (handle_ == NULL) {
    //导入libart.so
    library = kLibraryFallback; 
    handle_ = dlopen(library, kDlopenFlags);
    ...
  }
  //找到JNI_CreateJavaVM函数,把其地址JNI_CreateJavaVM_
  if (!FindSymbol(reinterpret_cast<void**>(&JNI_CreateJavaVM_), "JNI_CreateJavaVM")) {
    return false;
  }
  ...
  return true;
}

int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote)
{
    ...
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        return -1;
    }
}

extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
  return JniInvocation::GetJniInvocation().JNI_CreateJavaVM(p_vm, p_env, vm_args);
}

jint JniInvocation::JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
  //调用前面从libart.so中找到的创建虚拟机的函数
  return JNI_CreateJavaVM_(p_vm, p_env, vm_args);
}

  • JNIEnv是在Zygote初始化的时候调用libart.so中的"JNI_CreateJavaVM"方法创建的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值