在Android系统中,DVM、ART、应用程序进程和SystemServer进程都是由Zygote进程创建的,因此Zygote又称为“孵化器”。它是通过fork的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建一个DVM或者ART,因此通过fork而创建的应用程序进程和SystemServer进程可以在内部获取一个DVM或ART的实例副本。
备注:本文将结合Android8.0的源码看Zygote进程的启动过程以及Zygote进程做了哪些重要工作。
1. Zygote进程启动脚本
在init.rc中采用的是import类型语句来引入Zygote启动脚本,这些启动脚本都是由Android初始化语言来写的:
import /init.${ro.zygote}.rc
可以看出:init.rc中不会直接引入一个固定的文件,而是根据属性ro.zygote的内容来引入不同的文件。
从Android5.0开始,Android开始支持64位程序,Zygote就有了32位和64位的区别。所以这里就用ro.zygote属性来控制使用不同的Zygote启动脚本,从而就启动不同版本的Zygote进程。
ro.zygote属性的值有如下四种:
-
init.zygote32.rc
-
init.zygote32_64.rc
-
init.zygote64.rc
-
init.zygote64_32.rc
这些Zygote启动脚本都是放在system/core/rootdir/目录下。
1.1 init.zygote32.rc
表示支持纯32位程序,内容如下所示:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
根据Service类型语句的格式可知:
-
Zygote进程名称为zygote
-
执行程序是app_process
-
classname为main
-
如果audioserver、cameraserver、media、netd、wificond等进程终止时,Zygote进程会重启。
1.2 init.zygote32_64.rc
表示既支持32位程序也支持64位程序,内容如下所示:
service zygote /system/bin/app_process32 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
service zygote_secondary /system/bin/app_process64 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
class main
priority -20
user root
group root readproc
socket zygote_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
可以发现,脚本中有两个Service类型语句,说明会启动两个Zygote进程:
-
一个进程名为:zygote;执行程序为:app_process32,作为主模式
-
另一个进程名为:zygote_secondary;执行程序为:app_process64,作为辅模式
2. Zygote进程启动过程
在《从源码角度看Android系统init进程启动过程》一文中可知:init启动Zygote调用的是app_main.cpp的main函数中AppRuntime的start方法来启动Zygote进程。
代码路径:frameworks/base/cmds/app_process/app_main.cpp
main函数如下:
int main(int argc, char* const argv[])
{
...省略...
//传到的参数argv是“-Xzygote /system/bin --zygote --start-system-server”
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
//忽略第一个参数
argc--;
argv++;
...省略...
// 参数解析
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
++i;
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) { //注释1
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) { //注释2
startSystemServer = true;
} else if (strcm