一、启动的大致流程
所有的应用程序和系统服务,都是Zygote负责创建的,Zygote进程是通过复制自身的方式来创建System进程和应用程序进程的。 Zygote会在系统启动时创建一个虚拟机实例。Zygote进程启动完成之后,会将system进程启动起来,以便和系统的关键服务启动起来。例如AMS ContentService 和PMS等。
关注点:
java世界是何时创建的?
Zygote进程是怎样创建的?
二、Zygote的启动过程
1. zygote 的启动脚本
在(一)中1.1.节分析到 init.rc文件解析到一个名字为apppress 的一个service其代码片段如下:
(此段为Native层代码)
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
代码第二行,表示Zygote进程启动过程中内部创建一个zygote的socket。
运行在System进程中的AMS就是通过这个Socket来请求Zygote创建新的应用程序。
最终执行service_start函数
在中间执行了一系列函数,主要是Socket AMS在请求Zygote创建新的应用程序进程之前,会打开设备文件来连接到Zygote进程的Client端Socket
最终执行到app_process(在Zygote进程中加载应用程序)
2 Zygote进程的启动过程(前6个步骤)
时序图:
- app_process.main 通过对main函数的分析发现是由AppRuntime的start函数来进一步启动的。
- 分析AndroidRuntime类的start函数发现参数className=com.android.interna.os.ZygoteInit
;参数startSystemServer的值=true.
而关注点。虚拟机就是在这里创建的!
这个函数主要做了三件事:
一、调用函数startVM启动虚拟机
二、调用了函数StarReg注册了JNI方法
三、调用了com.androdi.internal.os.ZygoteInit类的main函数至此进入Java世界。
start函数如下:
/*
* Start the Android runtime. This involves starting the virtual machine
* and calling the "static void main(String[] args)" method in the class
* named by "className".
*/
void AndroidRuntime::start(const char* className, const bool startSystemServer)
{
......
char* slashClassName = NULL;
char* cp;
JNIEnv* env;
......
/* start the virtual machine */
if (startVm(&mJavaVM, &env) != 0)
goto bail;
/*
* Register android functions.
*/
if (startReg(env) < 0) {
LOGE("Unable to register all android natives\n");
goto bail;
}
/*
* We want to call main() with a String array with arguments in it.
* At present we only have one argument, the class name. Create an
* array to hold it.
*/
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;
jstring startSystemServerStr;
stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(2, stringClass, NULL);
assert(strArray != NULL);
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);
startSystemServerStr = env->NewStringUTF(startSystemServer ?
"true" : "false");
env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
/*
* Start VM. This thread becomes the main thread of the VM, and will
* not return until the VM exits.
*/
jclass startClass;
jmethodID startMeth;
slashClassName = strdup(className);
for (cp = slashClassName; *cp != '\0'; cp++)
if (*cp == '.')
*cp = '/';
startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
......
} else {
startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
......
} else {
env->CallStaticVoidMethod(startClass, startMeth, strArray);
......
}
}
......
}
3.ZygoteInit 的main函数(JAVA世界的入口)