Zygote进程(孵化器进程)启动流程分析
文章目录
- Zygote进程(孵化器进程)启动流程
- 1.Zygote简介
- 2.Zygote进程的创建
- 2.1 启动init进程:
- 2.2 init.rc脚本:
- 2.3 app_process文件
- 2.3.1 main方法
- 2.3.2 AppRuntime类(AndroidRuntime)
- 2.3.2.1 AndroidRuntime类的`start`方法
- 3.Zygote进程
- 3.1 ZygoteInit.main()
- 3.2 ZygoteInit.preload()预加载
- 3.2.1 常用类
- 3.2.2 常用资源
- 3.2.3 常用库
- 3.3 启动System Server
Zygote进程(孵化器进程)启动流程
1.Zygote简介
- Zygote进程是一个用户进程,由init进程(1号进程)fork而来。
- Zygote进程的主要任务是加载系统的核心类库(如Java核心库和Android核心库)和安卓系统服务(SystemService),然后进入一个循环,等待请求来创建新的 Android 应用程序进程。
- Zygote进程通过fork的方式创建新的应用程序进程。
2.Zygote进程的创建
Zygote进程在系统启动时由init进程创建。init进程是Linux系统中的第一个用户空间进程,它通过解析init.rc文件来启动各种服务和进程,包括Zygote。具体流程如下:
2.1 启动init进程:
- 系统启动后,内核会加载并运行
init进程
。 init进程
读取并解析init.rc
配置文件。
init进程的启动可参考Linux内核Kernel启动过程
2.2 init.rc脚本:
init.rc
文件中包含启动Zygote的指令脚本的主要代码:
// 创建zygote服务
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
// 创建zygote socket,与系统和应用程序做通信
socket zygote stream 660 root system
// 定义了zygote服务重启时的一些操作
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server:
- service zygote: 定义一个名为zygote的服务
- /system/bin/app_process:这是启动Zygote进程的可执行文件,64位系统为
app_process64
。 - -Xzygote:标志表明这是一个Zygote进程启动的特殊模式。
- /system/bin:指定进程的工作目录。
- –zygote:告诉app_process以Zygote模式启动。
- –start-system-server:Zygote启动时还要启动System Server进程,这是Android系统中管理关键系统服务的核心进程。
class main:
- 将Zygote服务归类为main类别。
- Android系统在启动过程中会启动所有“main”类别的服务。
socket zygote stream 660 root system:
创建了一个名为zygote的UNIX域Socket套接字,用于其他进程与Zygote进程通信。
onrestart write /sys/android_power/request_state wake:
当zygote服务重启时,系统应该将“/sys/android_power/request_state”文件的内容设置为“wake”,以唤醒设备。
onrestart write /sys/power/state on:
当zygote服务重启时,系统应该将“/sys/power/state”文件的内容设置为 “on”,以打开电源。
onrestart restart media:
当zygote服务重启时,系统应该重启媒体服务(如音频、视频等),以恢复媒体功能。
onrestart restart netd:
当zygote服务重启时,系统应该重启网络守护进程(netd),以恢复网络功能。
2.3 app_process文件
/system/bin/app_process是Android中的一个关键可执行文件,负责启动Zygote进程和应用进程。
Android14的app_process源码地址
2.3.1 main方法
app_process
主入口点是main
方法,它是整个进程启动流程的起点。以下是其主要代码和解释:
以下是关键代码说明:
int main(int argc, char* const argv[])
{// 创建并初始化AppRuntime对象runtimeAppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));// 初始化参数zygote,startSystemServer,application,niceName,className// 代码见源码,此处略// 解析命令行参数// 代码见源码,此处略// 构建传递给 Java 初始化类的参数列表// 代码见源码,此处略if (zygote) {// 调用AppRuntime的start方法,开始加载ZygoteInit类runtime.start("com.android.internal.os.ZygoteInit", args, zygote);} else if (!className.isEmpty()) {runtime.start("com.android.internal.os.RuntimeInit", args, zygote);} else {fprintf(stderr, "Error: no class name or --zygote supplied.\n");app_usage();LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");}
}
2.3.2 AppRuntime类(AndroidRuntime)
AppRuntime继承自AndroidRuntime(ART),是Android中的一个关键类,负责管理和启动 Android 应用程序或系统服务的 Java 虚拟机 (JVM)。
Android14的AndroidRuntime源码地址
2.3.2.1 AndroidRuntime类的start
方法
app_process
的main方法调用了AppRuntime
的start方法,也就是AppRuntime
的父类AndroidRuntime
的start方法
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{// 初始化Java Native Interface (JNI)。JNI是Java和C/C++之间的接口,它允许Java代码和C/C++代码相互调用JniInvocation jni_invocation;jni_invocation.Init(NULL);JNIEnv* env; // JNIEnv环境指针// 初始化虚拟机if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {return;}// 注册JNI方法if (startReg(env) < 0) {return;}/** 以下代码执行后,当前线程(即运行 AndroidRuntime::start 方法的线程)将成为Java虚拟机(JVM)的主线程,并且在调用env->CallStaticVoidMethod启动指定的Java类的 main 方法后,这个方法不会返回,直到 JVM 退出为止。(官方文档说明)*/// 将"com.android.internal.os.ZygoteInit"转换为"com/android/internal/os/ZygoteInit"char* slashClassName = toSlashClassName(className != NULL ? className : "");jclass startClass = env->FindClass(slashClassName);if (startClass == NULL) {// 没有找到ZygoteInit.main()方法} else {// 通过JNI调用ZygoteInit.main()方法jmethodID startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");}
}
- 创建虚拟机
- 注册JNI方法
- 通过JNI调用ZygoteInit.main()
3.Zygote进程
在AndroidRuntime
的start方法,通过JNI调用ZygoteInit.main(),系统第一次进入Java层(ZygoteInit是系统运行的第一个Java类),当前线程也正式成为Java虚拟机(JVM)的主线程。
Android14的ZygoteInit源码地址
3.1 ZygoteInit.main()
通过main方法完成资源预加载、启动系统服务等功能,为Launcher桌面程序做准备。
public static void main(String[] argv) {// 创建ZygoteServerZygoteServer zygoteServer = null;...// 预加载资源preload(bootTimingsTraceLog);...// 初始化ZygoteServerzygoteServer = new ZygoteServer(isPrimaryZygote);...// 通过fork的形式初始化SystemServerRunnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);if (r != null) {r.run();return;}...// 启动Loop,监听消息caller = zygoteServer.runSelectLoop(abiList);...
}
3.2 ZygoteInit.preload()预加载
通过preload方法预加载系统常用的类、资源和库,能够显著减少应用启动时的延迟,并通过共享这些预加载的内容来降低内存使用,提高系统性能。
static void preload(TimingsTraceLog bootTimingsTraceLog) {preloadClasses(); //加载常用的Java类preloadResources(); //加载常用的资源(如布局、图片等)preloadOpenGL(); //加载OpenGL库preloadSharedLibraries(); //加载常用的本地共享库preloadTextResources(); //加载常用的文本资源...
}
3.2.1 常用类
- Android框架中的基础类,如Activity、Service、BroadcastReceiver等。
- 常用的UI组件类,如TextView、Button、ImageView等。
3.2.2 常用资源
常用布局文件(layout)。
常用图片资源(drawable)。
常用字符串(strings.xml)。
3.2.3 常用库
标准C库(libc.so)。
图形处理库(libskia.so)。
OpenGL ES库(libGLESv2.so)。
3.3 启动System Server
System Server是Android系统中的关键进程,负责启动和管理核心系统服务。
启动过程的核心代码:
public static void main(String argv[]) {// 初始化ZygoteServerZygoteServer zygoteServer = new ZygoteServer();// 启动System Serverif (startSystemServer) {startSystemServer(abiList, socketName, zygoteServer);}// 进入Zygote的主循环,等待新进程的启动请求zygoteServer.runSelectLoop();
}private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer) {/* 调用native方法fork系统服务器 */int pid = Zygote.forkSystemServer(...);if (pid == 0) {// 在子进程中执行System Server的main方法handleSystemServerProcess(parsedArgs);}
}private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {// 通过反射调用SystemServer的main方法ClassLoader cl = ClassLoader.getSystemClassLoader();Class<?> clz = cl.loadClass("com.android.server.SystemServer");Method m = clz.getMethod("main", new Class[] { String[].class });m.invoke(null, new Object[] { parsedArgs.remainingArgs });
}
- ZygoteServer是一个Socket,Zygote进程通过这个Socket和SystemService及其他应用程序进程做通信
- 通过fork创建的SystemServer进程是一个独立运行的进程,避免SystemServer进程受到其他进程的影响。
- 关于SystemServer,后面还会更详细的介绍
如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~