frameworks/base/core/java/com/android/internal/os/ZygoteInit.java#main()
是怎么执行的 ? 这需要从虚拟机启动的执行开始说起。
虚拟机启动的入口从frameworks/base/core/jni/AndroidRuntime.cpp#start
方法开始
void AndroidRuntime::start(const char* className, const Vector<String8>& options)
{
jni_invocation.Init(NULL); //初始化JNI
JNIEnv* env; //JNI环境指针
if (startVm(&mJavaVM, &env) != 0) { //启动一个虚拟机,会给mJavaVM、env赋值
return;
}
onVmCreated(env); //虚拟机Created
//注册android的一些函数
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
//...
//通过env->FindClass 加载String字符串
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
//className是方法传参过来的,toSlashClassName是个转换的方法,把点变成斜杠之类的
char* slashClassName = toSlashClassName(className);
//找到frameworks/base/core/java/com/android/internal/os/ZygoteInit.java这个类
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
/* keep going */
} else {
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V"); //找ZygoteInit的main方法,其中jmethodID就是ArtMethod
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray); //传入类、方法、参数,通过反射调用ZygoteInit的main方法
}
}
}
//...
}
小结
可以看到,Android虚拟机的启动是在AndroidRuntime.cpp#start()
方法。
- 首先会初始化JNI
- 然后启动一个虚拟机
- 找到ZygoteInit.java这个类
- 找ZygoteInit的main方法
- 传入类、方法、参数,通过反射调用ZygoteInit的main方法
其他
源码为Android 5.1.0_r3