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