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"方法创建的