Zygote 是 Android 操作系统中的一种进程,可充当具有相同应用二进制接口 (ABI) 的所有系统和应用进程的根。
在现代设备(例如 Pixel 7 及更新型号)上,会有一个 64 位 Zygote 进程。此外,还有适用于主要 ABI 的 WebView Zygote,它是一种专门的 Zygote,包含运行 WebView 的进程专用的库和资源。
Zygote 执行的任务如下:
当 Android OS 初始化时,init 守护程序会生成 Zygote 进程。在某些双架构系统中,会生成两个 Zygote 进程(一个 64 位,一个 32 位)。本页仅介绍单一架构系统的情况。
Zygote 可以立即生成称为非专用应用进程 (USAP) 的进程,也可以等到应用需要时再生成进程。前一种选项必须通过系统属性或 Android 调试桥命令启用。如需详细了解如何将 Zygote 配置为立即生成进程,请参阅启用非专用应用进程池。
如果您的设备上启用了 USAP 池,则:
- 系统服务器使用 Unix 域套接字连接到池中的可用 USAP。系统服务器通过更改进程的 ID (PID)、cgroup 和其他信息,请求为供应用使用而预配置 USAP。
- 当 USAP 完成预配置后,它会使用 PID 回复系统服务器。
- 当某个应用占用一个 USAP 时,该 USAP 就不再属于该池。当池中的 USAP 数量达到 1 个或更少时,Zygote 会生成新的 USAP 来为池补充 USAP。
如果您的 Zygote 使用延迟求值机制来生成进程,则:
- 系统服务器收到应用需要进程的命令。
- 系统服务器使用 Unix 域套接字向相应的 Zygote 发送命令。
- Zygote 复刻进程并更改 PID、cgroup 和其他信息。
- 该进程完成后,将 PID 发送回 Zygote,然后 Zygote 将其传递回系统服务器。
启用 USAP 池
如需启用 USAP 池,请执行以下操作之一:
在
/build/make/target/product/runtime_libart.mk
中将dalvik.vm.usap_pool_enabled
系统属性设置为true
。运行以下命令:
adb shell am broadcast -a \"com.google.android.gms.phenotype.FLAG_OVERRIDE\" --es package \"com.google.android.platform.runtime_native\" --es user \"\*\" --esa flags \"usap_pool_enabled\" --esa values \"true\" --esa types \"string\" com.google.android.gms
此功能启用后,每个 Zygote 都会维护一个分支进程池,用于执行应用启动进程中与应用无关的部分。
排查 Zygote 问题
本部分介绍了 Zygote 相关问题的解决方案。
Zygote 崩溃
如果您的设备无法正常重新启动,并且日志或崩溃报告显示 Zygote 存在问题,有可能是因为您最近做出了导致 initd 或系统服务器崩溃的更改。修正代码应该可以解决此问题。
SELinux 拒绝或 IO 失败
Zygote 非常注重跨进程边界的文件描述符卫生情况。如果复刻时有文件描述符,但许可名单中却没有,我们会使用 dup
系统调用来执行 /dev/null
,以防止意外使用缓存的文件描述符来访问新打开的文件。
如果您要做出框架更改,更改包括尝试将资源加载到 Zygote 中,但收到 SELinux 拒绝或 IO 失败错误,请采取以下办法:
对于未命名的文件描述符,在调用
Restat
时将文件描述符添加到fds_to_ignore
向量中。对于已命名的文件描述符:
- 修改
WORKING_DIRECTORY/frameworks/base/core/jni/fd_utils.cpp
。 - 将该路径添加到打开文件的许可名单中。
- 修改