前言
上一章节已经梳理了通过加载libart.so, JNI_CreateJavaVM成功返回,虚拟机就处于就绪状态了,可以接受jni调用了。
虚拟机分为java和native两个层面,这两层间的通信就是jni,通常虚拟机的创建和管理都是在native层,然后通过jni来与java层互访,会有一个JNIEnv类型的指针变量,就是pEnv,他是以指向指针的指针做为参数的。这个JNIEnv指针是访问JVM的关键,真正的实现是JNIEnvExt。
art/runtime/jni_env_ext.h
#include <jni.h> ===> libnativehelper/include/include_jni/jni.h
struct JNIEnvExt : public JNIEnv {
static JNIEnvExt* Create(Thread* self, JavaVMExt* vm);
~JNIEnvExt();
}
涉及源码
platform/frameworks/base/core/jni/AndroidRuntime.cpp
/frameworks/base/core/jni/android_util_Binder.cpp
/frameworks/base/core/jni/core_jni_helpers.h
/libnativehelper/JNIHelp.cpp
/art/runtime/jni_internal.cc
一、虚拟机启动回调-onVmCreated
注册jni之前,虚拟机已经启动成功后,一个回调onVmCreated
onVmCreated,虚拟机成功创建完成,需要通过回调函数onVmCreate()通知用户,这里的调用者就是AndroidRuntime的继承类AppRuntime来完成,如果是zygote启动的,则不做任何逻辑,直接return。
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
... //打印一些日志,获取ANDROID_ROOT环境变量
onVmCreated(env);//表示虚拟创建完成,但是里面是空实现
if (startReg(env) < 0) {注册JNI函数
ALOGE("Unable to register all android natives\n");
return;
}
... //JNI方式调用ZygoteInit类的main函数
}
二、注册JNI
2.1 startReg
定义在platform/frameworks/base/core/jni/AndroidRuntime.cpp
int AndroidRuntime::startReg(JNIEnv* env)
{
ATRACE_NAME("RegisterAndroidNatives");
/*
* This hook causes all future threads created in this process to be
* attached to the JavaVM. (This needs to go away in favor of JNI
* Attach calls.)
*/
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
//设置Android创建线程的函数javaCreateThreadEtc,这个函数内部是通过Linux的clone来创建线程的,这个调用会让后面创建的新线程都会hooked到JavaVM上。后续线程专项会重点介绍
....
env->PushLocalFrame(200);//创建一个200容量的局部引用作用域,这个局部引用其实就是局部变量
if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) { //注册JNI函数
&

最低0.47元/天 解锁文章
829

被折叠的 条评论
为什么被折叠?



