当前位置: 首页 > news >正文

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进程

AndroidRuntimestart方法,通过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,后面还会更详细的介绍

如果对你有帮助,就一键三连呗(关注+点赞+收藏),我会持续更新更多干货~~


http://www.mrgr.cn/news/28674.html

相关文章:

  • Keithley吉时利2612B数字源表
  • Mysql数据库里的SSH连接
  • Linux 常用操作指令大揭秘(下)
  • 深入探讨 MySQL 配置与优化:从零到生产环境的最佳实践20241112
  • LabVIEW大数据处理
  • 平安人寿山西分公司:践行绿色金融,开启绿色新篇章
  • Android Framework(六)WMS-窗口显示流程——窗口内容绘制与显示
  • Java8的Optional简介
  • 计算机三级网络技术总结(三)
  • 在基于线程的环境中运行 MATLAB 函数
  • Mysql | 知识 | 幻读是如何解决的
  • 并查集的应用
  • Python3网络爬虫开发实战(15)Scrapy 框架的使用
  • 找搭子是什么意思?有没有找搭子的平台?靠谱找搭子软件推荐!
  • 7.4 溪降技术:滑行
  • 【机器学习】--- 自监督学习
  • 华硕产品资料的查询方法
  • 【Kubernetes】常见面试题汇总(二十一)
  • 如何避免长距离遗忘问题
  • 18、Python如何读写csv文件
  • 关于一道逻辑思维训练题的理解(手表、闹钟、标准时间的骗局)
  • 【计网面试真题】If-Modified-Since和Etag有什么区别
  • 简单的16位CPU(中央处理单元) verilog设计 (完整全部代码)
  • ST表(算法篇)
  • 音视频开发之旅(94)-多模态之Blip-2
  • 第一次安装Pytorch