您的位置:

Android Zygote源码分析

一、Zygote是什么

Zygote是Android系统启动过程中的一个进程,它是用来孵化新应用进程的。Zygote进程会先加载Android Framework,并执行一些初始化操作,然后等待系统创建新应用进程的请求。当一个新应用进程需要创建时,Zygote进程就会fork出一个子进程,并为新进程执行一些初始化操作,包括加载应用的类、资源等。

二、Zygote的启动流程

Zygote的启动流程可以分为三步:

1、系统启动时,init进程会调用/system/bin/start

``` /system/bin/start class_start /system/bin/app_process /system/bin --zygote --start-system-server ... ```

2、start脚本会调用app_process可执行文件,并将--zygote和--start-system-server两个参数传递给它。

``` app_process /system/bin --zygote --start-system-server ```

3、app_process根据--zygote参数,判断当前进程是否是Zygote进程,如果是,则执行Zygote的初始化操作,否则,app_process会根据传递给它的类名参数启动对应的应用进程。

三、Zygote的初始化操作

Zygote进程的初始化操作包括:

1、加载Android Framework

``` /** * @param systemServer 是否启动系统服务进程 */ void com_android_internal_os_Zygote_nativeInit(JNIEnv* env, jclass clazz, jboolean systemServer) { ... if (systemServer) { zygote_init(); } else { child_init(); } ... } ```

2、创建Zygote Socket

``` int createZygoteSocket(const char* socketName) { int fd; union { sockaddr addr; sockaddr_un unixAddr; } sockAddr; /** * 初始化socket地址 */ memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.unixAddr.sun_family = AF_UNIX; strcpy(sockAddr.unixAddr.sun_path, socketName); /** * 创建socket */ fd = socket(AF_UNIX, SOCK_STREAM, 0); /** * 绑定socket到地址 */ if (bind(fd, &sockAddr.addr, sizeof(sockAddr.unixAddr)) == -1) { ALOGE("bind('%s') failed: %s", socketName, strerror(errno)); return -1; } /** * 监听socket */ if (listen(fd, 5) == -1) { ALOGE("listen() failed: %s", strerror(errno)); return -1; } /** * 授权socket文件路径和进程UID之间的访问权限 */ if (chmod(socketName, 0777) == -1) { ALOGE("chmod('%s', 0777) failed: %s", socketName, strerror(errno)); return -1; } return fd; } ```

四、Zygote的通信协议

Zygote进程在创建新应用进程时,会通过Zygote Socket接收来自System Server进程的请求。请求数据格式如下:

``` struct { int32_t pid; // 请求进程的PID uid_t uid; // 请求进程的UID char* cmd; // 启动应用的命令,例如am start ... int32_t argc; // argv数组的长度 char** argv; // 传递给应用进程的参数列表 int32_t envc; // envp数组的长度 char** envp; // 传递给应用进程的环境变量列表 int32_t w, h; // 应用进程窗口的宽和高 int32_t sdkVersion; // 应用所用的SDK版本号 } StartArgs; ```

在接收到请求后,Zygote进程会fork出一个子进程,并传递请求的参数给子进程(argv数组、envp数组等)。新应用进程会继承与Zygote进程相同的类、资源、环境等,从而减少启动时间和内存消耗。

五、Zygote的优化

Zygote进程会在启动时预加载常用的类和资源,以便在孵化新应用进程时能够更快地初始化应用。此外,Zygote进程还会采用Copy on write(COW)技术,在fork出子进程时,共享与父进程相同的内存页面,以减少内存使用和启动时间。

六、总结

本文主要讲解了Android系统启动过程中的Zygote进程,介绍了Zygote的启动流程、初始化操作、通信协议以及优化措施。Zygote进程的孵化方式,充分利用系统资源,减少了应用启动时间和内存消耗,对提高系统性能起到一定的作用。