1. Android FrameWork之系统启动的流程:Zygote、SystemServer 与 Binder 的三角博弈

1.系统的启动流程图

内核进程:什么时候启动的(Kernel Processes)

用户进程:init进程

1.1.启动电源以及系统启动(Rom)

当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序Bootloader到RAM,然后执行。

1.2.引导程序BootLoader , 不是bootClassLoad

引导程序BootLoader是在Android操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。

1.3.Linux内核启动(kernel)

内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc文件,并启动init进程。

1.4.init进程启动 (用户的第一个进程)

初始化和启动属性服务,并且启动Zygote进程。

1). servermanger(Binder管家)

2). zygote(应用孵化器)

3). surfaceFling1. - (图形服务)

1.5.Zygote进程启动

创建JavaVM并为JavaVM注册JNI,创建服务端Socket,启动SystemServer进程。

1). 虚拟机

2). SystemServe

3). jni

  • 关键技术:Copy-On-Write(COW)共享内存

1.6.SystemServer进程启动

  • 分级服务启动(SystemServer分阶段加载)

启动Binder线程池和SystemServiceManager,并且启动各种系统服务。

AMS,PMS, WMS

  • 核心服务启动顺序

    阶段 服务示例 依赖关系
    Bootstrap ActivityManagerService (AMS) 基础服务
    PowerManagerService
    Core BatteryService 依赖Bootstrap
    UsageStatsService
    Other WindowManagerService (WMS) 依赖AMS
    PackageManagerService (PMS)
  • 关键方法SystemServer.run()

1.7.Launcher启动

被SystemServer进程启动的ActivityManagerService会启动Launcher,Launcher启动后会将已安装应用的快捷图标显示到界面上。

  • 核心流程

    1. PMS解析CATEGORY_HOME应用
    2. Zygote孵化Launcher进程
    3. 加载应用图标(通过PMS获取数据)
    4. 渲染桌面UI

系统进程的启动顺序:

Init进程-->Zygote进程-->SystemServer进程-->应用进程(Launcher)

其他: 开机动画控制机制: 和launcher关系

  1. 启动流程

    csharp 复制代码
    // SurfaceFlinger.cpp
    void startBootAnim() {
        property_set("service.bootanim.exit", "0");
        property_set("ctl.start", "bootanim"); // 触发init启动服务
    }
  2. 关闭条件

    scss 复制代码
    // BootAnimation.cpp
    void checkExit() {
        property_get("service.bootanim.exit", value, "0");
        if (atoi(value)) requestExit(); // AMS通知退出
    }
  3. 自定义动画

    • 替换路径:/system/media/bootanimation.zip

    • 制作规范:

      • desc.txt:定义分辨率/帧率
      • part0/:首帧图片序列
      • part1/:循环帧序列

2. Init进程(用户空间第一个进程)

流程图:

  • 源码路径system/core/init/init.cpp

  • 核心任务

    scss 复制代码
    int main() {
      // 1. 创建目录/挂载分区
      mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
      
      // 2. 启动属性服务
      property_init();
      start_property_service();
      
      // 3. 解析init.rc
      LoadBootScripts();  // 启动zygote等关键服务
    }
  • 关键点 :通过socketpair和信号机制守护子进程(如zygote)

init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等。

init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init。

init 进程是 Linux 系统中用户空间的第一个进程,进程号为 1

2.1 问题: init进程是如何起来的 ?

selinux: 进程,权限

2.2 总结起来init进程主要做了三件事:

1.创建一些文件夹并挂载设备

2.初始化和启动属性服务

3.解析init.rc配置文件并启动zygote进程


子进程可以继承父进程的资源

2.3 main 方法里面,因为它是c语言,有 148 行代码(不包括子函数代码)具体分为四个步骤:

.init.rc和init.cpp是干嘛的

1).创建目录,挂载分区(android Q分区有所改变)

2).解析启动脚本. init.rc 文件是 Android 系统的重要配置文件,位于 /system/core/rootdir/init.rc

3).启动解析的服务

4).守护解析的服务。

问题:init 进程是如何守护子进程的?

socketpair,信号sigle

初始化epoll,依次设置signal、property、keychord这3个fd可读时相对应的回调函数。进入无线循环,用来响应各个进程的变化与重建。

5). SELinux 初始化

  • 加载安全策略并切换执行上下文

2.4 init创建了哪些服务?

init 进程在解析 init.rc 时,创建了下面的进程

1). 创建了 zygote(创建 App 应用的服务)、

2). servicemanager (client 与 service 通信管理的服务)

问题:ServiceManager 是什么时候启动 的? init的时候

ServiceManager 管理 SystemServer

arduino 复制代码
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());

mSystemServiceManager.startService(AlarmManagerService.class);

publishBinderService(Context.ALARM_SERVICE, mService);

/**

     * Publish the service so it is accessible to other services and apps.

     */

    protected final void publishBinderService(String name, IBinder service) {

        publishBinderService(name, service, false);

    }

    /**

     * Publish the service so it is accessible to other services and apps.

     */

    protected final void publishBinderService(String name, IBinder service,

            boolean allowIsolated) {

        ServiceManager.addService(name, service, allowIsolated);


    }

总结:不管是 ServiceManager.addService 还是 mSystemServiceManager.startService 都是调用的 ServiceManager.addService 方法。

3). surfaceflinger(显示渲染服务)

4). media(多媒体服务) 等 service 进程。

问题: Init 进程如何防止僵尸进程?

→ 通过 waitpid() 回收子进程资源

问题:init如何启动zygote进程的?

frameworks/base/cmds/app_process/app_main.cpp

c 复制代码
int main(int argc, char* const argv[])
{
    ...
    // 根据启动参数判断应用进程的启动模式
    if (zygote) {
        // 以Zygote模式启动,启动Zygote初始化类
        // Zygote是Android系统的核心进程,负责孵化其他应用进程
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote); // 1
    } else if (className) {
        // 以普通应用模式启动,启动运行时初始化类
        // 用于初始化应用运行时环境
        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
    } else {
        // 错误情况:既没有指定类名也没有使用--zygote参数
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        // 打印应用使用说明
        app_usage();
        // 记录致命错误日志
        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
        // 返回错误码10
        return 10;
    }
}

2.5 子进程守护机制

  • 监控方式SIGCHLD 信号 + epoll 监听

  • 重启策略(Service 配置项):

    c 复制代码
    class Service {
      std::string name_;         // 服务名
      std::vector<std::string> args_; // 执行命令
      pid_t pid_ = 0;           // 进程ID
      int flags_ = 0;           // 标志位(如 SVC_ONESHOT)
      time_t time_started_;     // 启动时间
      int crash_count_ = 0;     // 崩溃计数
    };
  • 关键行为

    • 崩溃超过 4 次则标记为禁用
    • 配置 onrestart 触发关联服务重启

2.6 启动的核心服务

Init 进程直接启动的关键守护进程:

服务名称 执行文件 作用
servicemanager /system/bin/servicemanager Binder IPC 服务管理器
zygote /system/bin/app_process 应用进程孵化器
surfaceflinger /system/bin/surfaceflinger 图形合成服务
ueventd /sbin/ueventd 设备节点热插拔管理
logd /system/bin/logd 系统日志服务

3. Zygote进程启动

流程图:

3.1. Zygote核心职责

  • 预加载系统资源(类、资源、共享库)
  • 监听 Socket 请求,孵化新应用进程
  • 启动 SystemServer 进程

设计思想

  • Copy-On-Write (COW) :子进程共享父进程只读内存,修改时才复制
  • 单例预加载:避免每个应用重复加载相同资源
  • Socket IPC:轻量级通信(Binder 未就绪时)

  • 入口frameworks/base/cmds/app_process/app_main.cpp

  • 核心流程

    scss 复制代码
    // ZygoteInit.java
    public static void main(String[] args) {
      // 1. 预加载资源(共享内存优化)
      preload(); // 加载类/资源/图形库
      
      // 2. 启动SystemServer
      if (args.contains("start-system-server")) {
        forkSystemServer(); 
      }
      
      // 3. 进入Socket监听循环
      runSelectLoop(); // 等待AMS请求孵化新进程
    }

启动SystemServer进程

接下来查看startSystemServer函数,代码如下所示。

java 复制代码
/**
 * 启动系统服务进程(system_server)的方法
 * system_server是Android系统的核心服务进程,管理着系统的各种关键服务
 * @param abiList 支持的ABI列表
 * @param socketName 用于通信的Socket名称
 * @return 启动成功返回true
 * @throws MethodAndArgsCaller 方法调用异常
 * @throws RuntimeException 运行时异常
 */
private static boolean startSystemServer(String abiList, String socketName)
        throws MethodAndArgsCaller, RuntimeException {

    ...

    /* 硬编码启动系统服务的命令行参数 */
    /*1*/
    String args[] = {
        "--setuid=1000",  // 设置进程用户ID为1000(系统用户)
        "--setgid=1000",  // 设置进程组ID为1000(系统组)
        // 设置进程附加组ID,包含各种系统权限相关的组
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007,3009,3010",
        "--capabilities=" + capabilities + "," + capabilities,  // 设置进程能力集
        "--nice-name=system_server",  // 设置进程的友好名称(在进程列表中显示)
        "--runtime-args",  // 指示后续参数为运行时参数
        "com.android.server.SystemServer",  // 系统服务的主类名
    };

    // 用于存储解析后的参数对象
    ZygoteConnection.Arguments parsedArgs = null;

    // 存储fork出的系统服务进程ID
    int pid;

    try {
        // 解析命令行参数为结构化对象
        parsedArgs = new ZygoteConnection.Arguments(args); //2
        // 应用调试器相关的系统属性到解析后的参数
        ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
        // 应用invoke-with相关的系统属性到解析后的参数
        ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

        /*3*/
        // 通过Zygote fork出系统服务进程
        // 参数包括:用户ID、组ID、附加组ID、调试标志、父进程描述符、允许的能力集、有效的能力集
        pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.debugFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    // pid为0表示当前代码在新fork出的子进程(system_server)中执行
    if (pid == 0) {
        // 如果存在第二个Zygote进程,等待其启动完成
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }

        // 处理系统服务进程的初始化工作
        handleSystemServerProcess(parsedArgs); //4
    }

    // 返回启动成功
    return true;
}

3.2 Zygote进程的创建过程

Java里面的调用:

java 复制代码
public class ZygoteInit {

    /**
     * Zygote进程的主入口方法
     * Zygote是Android系统的核心进程,负责孵化应用进程和系统服务进程
     * @param argv 命令行参数
     */
    public static void main(String argv[]) {
        // 创建Zygote服务器实例,用于管理进程间通信的Socket
        ZygoteServer zygoteServer = new ZygoteServer();

        // 标记Zygote启动,确保在此期间创建线程会抛出错误
        // 防止在Zygote初始化完成前创建线程,保证初始化的线程安全性
        ZygoteHooks.startZygoteNoThreadCreation();

        // 将Zygote放入自己的进程组,便于进程管理和信号处理
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        // 用于存储后续需要执行的任务
        final Runnable caller;
        try {
            // 向tron报告Zygote启动时间,除非是运行时重启
            if (!"1".equals(SystemProperties.get("sys.boot_completed"))) {
                MetricsLogger.histogram(null, "boot_zygote_init",
                        (int) SystemClock.elapsedRealtime());
            }

            // 根据进程位数设置启动时间跟踪标签
            String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";
            TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                    Trace.TRACE_TAG_DALVIK);
            bootTimingsTraceLog.traceBegin("ZygoteInit");
            
            // 启用DDMS调试功能
            RuntimeInit.enableDdms();

            // 解析命令行参数
            boolean startSystemServer = false;       // 是否启动系统服务进程
            String socketName = "zygote";            // Socket名称
            String abiList = null;                   // 支持的ABI列表
            boolean enableLazyPreload = false;       // 是否启用延迟预加载
            for (int i = 1; i < argv.length; i++) {
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = true;
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                    socketName = argv[i].substring(SOCKET_NAME_ARG.length());
                } else {
                    throw new RuntimeException("Unknown command line argument: " + argv[i]);
                }
            }

            // 检查ABI列表是否提供,未提供则抛出异常
            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }

            // 从环境变量注册服务器Socket,用于接收孵化新进程的请求
            zygoteServer.registerServerSocketFromEnv(socketName);
            
            // 预加载资源和类(除非启用延迟预加载)
            // 在某些配置下,会延迟预加载直到第一次fork之前
            if (!enableLazyPreload) {
                bootTimingsTraceLog.traceBegin("ZygotePreload");
                // 记录预加载开始时间
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
                    SystemClock.uptimeMillis());
                // 执行预加载操作(资源、类等)
                preload(bootTimingsTraceLog);
                // 记录预加载结束时间
                EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
                    SystemClock.uptimeMillis());
                bootTimingsTraceLog.traceEnd(); // ZygotePreload
            } else {
                // 重置优先级为默认值
                Zygote.resetNicePriority();
            }

            // 初始化后执行一次GC,清理启动过程中产生的垃圾
            bootTimingsTraceLog.traceBegin("PostZygoteInitGC");
            gcAndFinalize();
            bootTimingsTraceLog.traceEnd(); // PostZygoteInitGC

            bootTimingsTraceLog.traceEnd(); // ZygoteInit
            
            // 禁用跟踪,确保fork出的进程不会继承Zygote的旧跟踪标签
            Trace.setTracingEnabled(false, 0);

            // 初始化原生安全设置
            Zygote.nativeSecurityInit();

            // Zygote进程卸载根存储区域
            Zygote.nativeUnmountStorageOnInit();

            // 停止Zygote的线程创建限制
            ZygoteHooks.stopZygoteNoThreadCreation();

            // 如果需要启动系统服务进程
            if (startSystemServer) {
                //  fork系统服务进程,返回值在父进程(zygote)中为null,在子进程(system_server)中为非null
                Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

                // 在子进程(system_server)中执行返回的任务
                if (r != null) {
                    r.run();
                    return;
                }
            }

            Log.i(TAG, "Accepting command socket connections");

            // 进入选择循环,等待并处理新的进程创建请求
            // 在子进程中fork后会提前返回,在zygote进程中则会一直循环
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with exception", ex);
            throw ex;
        } finally {
            // 关闭服务器Socket(通常在异常情况下)
            zygoteServer.closeServerSocket();
        }

        // 在子进程中,退出选择循环后执行相应的命令
        if (caller != null) {
            caller.run();
        }
    }
}

Zygote启动流程就讲到这,Zygote进程共做了如下几件事:

1.创建AppRuntime并调用其start方法,启动Zygote进程。

2.通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。(ZygoteInit.java).换句换说Zygote开创了Java框架层

3.ZygoteInit这个类 ,里面有个懒加载!它还有什么用,它会加载很多很多类。preload_class..把系统公共的累加载到系统内存

4.里面有个zygotesever,是用socket,通过registerZygoteSocket创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。

zygote 的主要工作如下:(4大重要的作用)

  • 1. 创建 java 虚拟机 AndroidRuntime
    1. 启动SystemServer进程。
    1. 创建jni startReg()
  • 4.预加载资源

最后再来总结一下:

Zygote 进程是由 init 进程解析 init.rc 脚本创建的,其具体的执行源码是在 App_main.main 方法,

首先会创建一个虚拟机实例,然后注册 JNI 方法,最后通过 JNI 调用进入 Java 世界来到 ZygoteInit.main 方法。

在 Java 世界中我们会为 Zygote 注册 socket 用于进程间通信,预加载一些通用的类和资源,

启动 system_server 进程,循环等待孵化创建新的进程。

完整的4步骤:

1.创建虚拟机, 启动虚拟机VM startVm();

  1. 创建jni, startReg()

2.预加载资源

3.循环等待孵化创建新的进程

Zygote 最后是一个死循环,不断的等待远程跟我通信,创建子进程 ,Os.poll(pollFds, -1); 会阻塞等待有没有新的文件描述符发生变化

4.启动SystemServer进程。

  1. 创建 socket 服务,接受 ActivityManagerService 的应用启动请求

Zygote 开启 socket 服务,然后调用 runSelectLoop 方法进入无限循环中等待 socket 消息

问题:为什么在zygote进程创建虚拟机

因为它里面要fork,APP进程, 进程对应虚拟机,虚拟机是内存

问题1:为什么 预加载资源?

因为其他应用都是通zygote进程创建,资源可以共享,继承父进程的资源!copyOnWrite

所有的 app 进程都是由 Zygote 孵化(fork)而来的。fork 有一个 copyonwrite 技术可以复用父进程的资源,好处就是不需要再去额外的花费时间去加载资源,

不好的地方:进程一创建他的内存就比较大

问题2:资源加载加载了哪些资源?

android.jar。openGL等!

csharp 复制代码
private static void preloadSharedLibraries() {
    Log.i(TAG, "Preloading shared libraries...");
    System.loadLibrary("android");
    System.loadLibrary("compiler_rt");
    System.loadLibrary("jnigraphics");

    try {
        System.loadLibrary("sfplugin_ccodec");
    } catch (Error | RuntimeException e) {
        // tolerate missing sfplugin_ccodec which is only present on Codec 2 devices
    }
}

/**
 * This call loads the graphics driver by making an OpenGL or Vulkan call.  If the driver is
 * not currently in memory it will load and initialize it.  The OpenGL call itself is relatively
 * cheap and pure.  This means that it is a low overhead on the initial call, and is safe and
 * cheap to call later.  Calls after the initial invocation will effectively be no-ops for the
 * system.
 */
static native void nativePreloadGraphicsDriver();

private static void maybePreloadGraphicsDriver() {
    if (!SystemProperties.getBoolean(PROPERTY_DISABLE_GRAPHICS_DRIVER_PRELOADING, false)) {
        nativePreloadGraphicsDriver();
    }
}

context代表的是什么?

就是加载的资源!上面的这种资源!

问题3:如何优化开机启动?

资源加载方面通过多线程

问题:应用开发为什么要用多进程:

QQ音乐(9个进程),获取更多资源,进程之间相互不影响,为了有更好的体验!

可以优化启动速度:很多加载库不用一开始就加载,可以先看到页面,然后再是音乐播放

因为多个进程,application会执行多次,不同进程加载不同的内容!

优化启动速度:可以用多线程么?

问题4:可以让init创建别的进程吗?加快启动速度?

应该是不可以,zygote进程是init进程

问题5:zygote进程是init如何创建的?

Zygote 进程是由 init 进程解析 init.rc 脚本创建的

问题: zygote是由什么进程创建的

init进程

问题6: 为什么要设计zygote?

因为同一用它来创建进程,方便管理

为什么zygote进程通信的时候用socket,不用binder?

因为安全,binder容易被hook,还没有启动相关的东西, 第二点:为了cs架构的设计理念!

问题7:zygote进程如果挂了会怎么样?

手机会重启,因为很多服务用不了

问题8:zygote进程是如何从c进程转到java进程

jni, C调用java !就是通过反射

3.3 . 预加载机制preload()

scss 复制代码
 static void preload() {
   preloadClasses();  // 加载 2000+ 系统类
   preloadResources(); // 系统资源(drawables, colors)
   preloadOpenGL();    // 图形库
   preloadSharedLibraries(); // libandroid, libcompiler_rt
   preloadTextResources();   // 字体/文本资源
 }
  • 优化原理:通过 COW 机制,子进程直接共享内存页

  • 配置文件/system/etc/preloaded-classes

3.4 . 进程孵化(Fork 机制)

  • SystemServer 创建

    scss 复制代码
    private static Runnable forkSystemServer() {
      // 1. 设置进程参数
      String args[] = {"--setuid=1000", "--setgid=1000", "com.android.server.SystemServer"};
      
      // 2. 调用 Native 层 fork
      pid = Zygote.forkSystemServer(uid, gid, gids, ...);
      
      // 3. 子进程初始化
      if (pid == 0) {
        return handleSystemServerProcess(parsedArgs);
      }
    }
  • 应用进程创建

    scss 复制代码
    // ZygoteConnection.java
    Runnable processCommand() {
      // 解析 AMS 请求参数
      pid = Zygote.forkAndSpecialize(uid, gid, ...);
      if (pid == 0) {
        // 子进程执行入口
        return handleChildProc(args, descriptors, childPipeFd);
      }
    }

3.5 . Socket 通信模型

  • 服务端初始化: // ZygoteServer.java void registerServerSocket(String socketName) { socket = new LocalServerSocket(socketName); // 地址:/dev/socket/zygote }

  • 请求处理循环: Runnable runSelectLoop() { while (true) { // 1. 监听 Socket 事件 int index = selectReadable(peers);

    kotlin 复制代码
        // 2. 新连接:加入 peers 列表
        // 3. 请求处理:读取 AMS 发来的参数
        ZygoteCommand command = peers.get(index).processCommand();
        
        // 4. 执行 fork
        if (command != null) return command;
      }
    }

4. AMS,PMS,WMS的创建 SyetemServer进程

  • 启动者 :Zygote 通过 fork() 创建。

  • 关键服务初始化顺序

    1. 引导服务

      • ActivityManagerService (AMS):应用生命周期管理。
      • PowerManagerService (PMS):电源管理。
      • PackageManagerService (PMS):应用包管理。
    2. 核心服务

      • WindowManagerService (WMS):窗口管理、输入事件分发。
      • DisplayManagerService:显示管理。
    3. 其他服务AudioServiceSensorService 等。

  • 服务注册 :所有服务通过 ServiceManager.addService() 注册 Binder 接口(例如 AMS 注册为 activity)。

SystemServer 是 Android 系统的核心进程,承载了所有关键系统服务(如 AMS、PMS、WMS)。其启动与运行机制如下:


4.1、创建过程(由 Zygote 进程 fork 完成)

  1. 启动触发

    • Zygote 启动时通过 --start-system-server 参数触发 SystemServer 的创建。
    • ZygoteInit.main() 中解析参数并调用 `forkSystemServer()。
  2. 参数配置

    SystemServer 的启动参数硬编码在 startSystemServer() 中,包括:

    arduino 复制代码
    String args[] = {
        "--setuid=1000",         // UID 设为 system 用户
        "--setgid=1000",         // GID 设为 system 组
        "--setgroups=1001,1002,...", // 权限组(涵盖网络、存储等)
        "--capabilities=130104352,130104352", // Linux 能力集
        "--nice-name=system_server", // 进程名
        "com.android.server.SystemServer" // 入口类
    }; :cite[3]:cite[6]:cite[7]
  3. 进程 fork

    • 调用 Zygote.forkSystemServer() → JNI 层 nativeForkSystemServer() → 最终执行 ForkAndSpecializeCommon()67。
    • 关键机制 :Zygote 通过 waitpid() 监控 SystemServer 状态,若其异常退出会重启 Zygote。

4.2、初始化流程(在 SystemServer 进程内执行)

  1. 环境准备

    • 关闭从 Zygote 继承的 Socket(仅 Zygote 需监听请求。
    • 调用 RuntimeInit.zygoteInit() 初始化通用环境(时区、日志等)。
  2. 启动 Binder 通信

    • 通过 JNI 调用 onZygoteInit() → 启动 Binder 线程池:

      ruby 复制代码
      sp<ProcessState> proc = ProcessState::self();
      proc->startThreadPool(); // 启动 Binder IPC 线程池:cite[3]:cite[4]
  3. 执行 SystemServer.main()

    • 通过反射调用 com.android.server.SystemServer.main()

    • 入口方法核心步骤

      typescript 复制代码
      public static void main(String[] args) {
          System.loadLibrary("android_servers"); // 加载 JNI 库
          run(); // 调用 SystemServer.run()
      } :cite[3]:cite[6]

4.3 、核心服务启动(SystemServer.run()

  1. 基础初始化

    • 创建主线程 Looper、系统上下文(SystemContext)、SystemServiceManager
  2. 分阶段启动服务

    阶段 服务示例 作用
    Bootstrap ActivityManagerService (AMS) 应用生命周期管理
    PowerManagerService 电源管理
    Core BatteryService 电池状态监控
    UsageStatsService 应用使用统计
    Other WindowManagerService (WMS) 窗口管理与事件分发
    PackageManagerService (PMS) 应用安装与权限管理16
  3. 服务依赖管理

    • AMS 最先启动,因其是其他服务(如 PMS)的依赖基础6。
    • 所有服务通过 ServiceManager.addService() 注册 Binder 接口,供应用调用。
  4. 启动完成回调

    调用 ActivityManagerService.systemReady(),触发 Launcher 启动。


4.4 、SystemServer 的核心地位

  1. 系统服务容器
    90% 的系统服务(如 BluetoothService、SensorService)以线程形式运行其中。
  2. 安全隔离层
    应用进程无直接硬件访问权限,必须通过 SystemServer 的 Binder 代理操作设备。
  3. 生死监控(Watchdog)
    内置看门狗模块,检测服务线程死锁,超时则重启系统。

4.5 、关键设计机制

  1. 与 Zygote 的生死绑定

    • SystemServer 崩溃会导致 Zygote 自杀重启(通过 waitpid() 监控实现)。
  2. 延迟服务加载

    非关键服务(如蓝牙)按需启动,减少开机时间6。

  3. 主线程事件循环

    通过 Looper.loop() 监听 Binder 调用与系统事件。


4.6 、典型问题分析

  1. 为何 SystemServer 不直接由 init 启动?

    • 需复用 Zygote 预加载的 Java 环境(类/资源),避免重复初始化。
  2. 系统卡顿与 SystemServer 的关系?

    • Watchdog 超时或 Binder 线程池阻塞会导致 ANR,甚至系统重启。
  3. 开机优化方向

    • 减少 main() 中的同步操作(如文件 I/O),并行初始化独立服务。

4.7 SyetemServer进程是 Zygote 进程 fork 创建的!(通过C代码)

zyotoinit() systemServer() 开始的时候只有uid,还没有pid,pid是什么呢?

ini 复制代码
// fork 创建 system_server 进程,后面会具体分析
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
        null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);

入口:SystemServer里面的main函数!

arduino 复制代码
public final class SystemServer {


/**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
    new SystemServer().run();
}

SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。启动系统的各种服务,在注释3中的startBootstrapServices函数中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务

在注释4处的函数中则启动了BatteryService、UsageStatsService和WebViewUpdateService。

注释5处的startOtherServices函数中则启动了CameraService、AlarmManagerService、VrManagerService等服务,这些服务的父类为SystemService。

从注释3、4、5的函数可以看出,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务为一些非紧要和一些不需要立即启动的服务。

scss 复制代码
// 启动引导服务 
startBootstrapServices();
// 启动核心服务 
startCoreServices();
// 启动其他服务
startOtherServices();

总结SyetemServer进程:

SyetemServer在启动时做了如下工作:

1.启动Binder线程池,这样就可以与其他进程进行通信。(通过java调用c启动的)

2.创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理。

3.启动各种系统服务。(AMS,PMS)

在这里,基本上都是java代码。

问题:ams,pms是什么时候启动的?

就是在systemServer进程启动的

在启动根服务

ini 复制代码
private void startBootstrapServices() {
    // 阻塞等待与 installd 建立 socket 通道
    Installer installer = mSystemServiceManager.startService(Installer.class);

    // 启动服务 ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);

    // 启动服务 PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mPackageManager = mSystemContext.getPackageManager();

    // 设置 AMS , 把自己交给 ServiceManager. addService 去管理
    mActivityManagerService.setSystemProcess();

...
}

启动其他服务:watchdog,IMS,ServiceManager注册服务,准备AMS,PMS,WMS

scss 复制代码
private void startOtherServices() {
    // 启动闹钟服务
    mSystemServiceManager.startService(AlarmManagerService.class);
    // 初始化 Watchdog
    final Watchdog watchdog = Watchdog.getInstance();
    watchdog.init(context, mActivityManagerService);
    // 输入管理的 service
    inputManager = new InputManagerService(context);
    // WindowManagerService
    wm = WindowManagerService.main(...);
    // InputManagerService 和 WindowManagerService 都交给 ServiceManager 管理
    ServiceManager.addService(Context.WINDOW_SERVICE, wm);
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
    // 启动input
    inputManager.start();
    // 显示启动界面
    ActivityManagerNative.getDefault().showBootMessage(...);
    // 状态栏管理
    statusBar = new StatusBarManagerService(context, wm);
    // JobSchedulerService
    mSystemServiceManager.startService(JobSchedulerService.class);
...
    // 准备好了 wms,  pms, ams 服务
    wm.systemReady();
    mPackageManagerService.systemReady();
    mActivityManagerService.systemReady();
}

里面有一个watchDog:

ini 复制代码
final Watchdog watchdog = Watchdog.getInstance();
watchdog.start();

private Context mSystemContext;
private SystemServiceManager mSystemServiceManager;

创建了系统上下文!

ini 复制代码
private void createSystemContext() {
    ActivityThread activityThread = ActivityThread.systemMain();
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

启动systemUi

ini 复制代码
private static void startSystemUi(Context context, WindowManagerService windowManager) {
    PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
    Intent intent = new Intent();
    intent.setComponent(pm.getSystemUiServiceComponent());
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    //Slog.d(TAG, "Starting service: " + intent);
    context.startServiceAsUser(intent, UserHandle.SYSTEM);
    windowManager.onSystemUiStarted();
}

AMS和PMS是SystemServer是里面的一个对象!

arduino 复制代码
public final class SystemServer {

    private static final String TAG = "SystemServer";

    private Context mSystemContext;
    private SystemServiceManager mSystemServiceManager;

    // TODO: remove all of these references by improving dependency resolution and boot phases
    private PowerManagerService mPowerManagerService;
    private ActivityManagerService mActivityManagerService;
    private WindowManagerGlobalLock mWindowManagerGlobalLock;
    private WebViewUpdateService mWebViewUpdateService;
    private DisplayManagerService mDisplayManagerService;

AMS启动的时候干了什么事情?

源码:任务栈管理

ini 复制代码
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {

 
@VisibleForTesting
public ActivityManagerService(Injector injector, ServiceThread handlerThread) {
    final boolean hasHandlerThread = handlerThread != null;
    mInjector = injector;
    mContext = mInjector.getContext();
    mUiContext = null;
    mAppErrors = null;
    mPackageWatchdog = null;
    mAppOpsService = mInjector.getAppOpsService(null /* file */, null /* handler */);
    mBatteryStatsService = null;
    mHandler = hasHandlerThread ? new MainHandler(handlerThread.getLooper()) : null;
    mHandlerThread = handlerThread;
    mConstants = hasHandlerThread
            ? new ActivityManagerConstants(mContext, this, mHandler) : null;
    final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
    mProcessList.init(this, activeUids);
    mLowMemDetector = null;
    mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);

    mIntentFirewall = hasHandlerThread
            ? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null;
    mProcessCpuThread = null;
    mProcessStats = null;
    mProviderMap = null;
    // For the usage of {@link ActiveServices#cleanUpServices} that may be invoked from
    // {@link ActivityStackSupervisor#cleanUpRemovedTaskLocked}.
    mServices = hasHandlerThread ? new ActiveServices(this) : null;
    mSystemThread = null;
    mUiHandler = injector.getUiHandler(null /* service */);
    mUserController = hasHandlerThread ? new UserController(this) : null;
    mPendingIntentController = hasHandlerThread
            ? new PendingIntentController(handlerThread.getLooper(), mUserController) : null;
    mProcStartHandlerThread = null;
    mProcStartHandler = null;
    mHiddenApiBlacklist = null;
    mFactoryTest = FACTORY_TEST_OFF;
}

RuntimeInit: 异常处理!

java 复制代码
private static class LoggingHandler implements UncaughtExceptionHandler {
    public volatile boolean mTriggered;

    private LoggingHandler() {
        this.mTriggered = false;
    }

    public void uncaughtException(Thread t, Throwable e) {
        this.mTriggered = true;
        if (!RuntimeInit.mCrashing) {
            if (RuntimeInit.mApplicationObject == null && 1000 == Process.myUid()) {
                RuntimeInit.Clog_e("AndroidRuntime", "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
            } else {
                StringBuilder message = new StringBuilder();
                message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
                String processName = ActivityThread.currentProcessName();
                if (processName != null) {
                    message.append("Process: ").append(processName).append(", ");
                }

                message.append("PID: ").append(Process.myPid());
                RuntimeInit.Clog_e("AndroidRuntime", message.toString(), e);
            }

        }
    }
}

问题:AMS,PMS,WMS的作用是干嘛的?

问题:java种,类只能继承一个类,那么如果要继承2个类的功能,要怎么做?

scala 复制代码
   public static final class Lifecycle extends SystemService {

        private final ActivityManagerService mService;
        public Lifecycle(Context context) {

            super(context);

            mService = new ActivityManagerService(context);

        }
        @Override
   public void onStart() {

            mService.start();

        }

        public ActivityManagerService getService() {

            return mService;

        }

    }

问题: 3者的关系是怎么样的?

SystemServer : 系统的服务器一样, 管理90个进程

SystemServiceManager

ServiceManager


总结 :SystemServer 作为 Android 的"服务中枢",其通过 分阶段启动Binder 线程池Watchdog 守护 三大机制,确保系统服务的可靠运行。设计精髓在于平衡效率(资源共享)与稳定性(进程隔离)

5. Launcher启动流程(AMS+PMS)

Launcher 启动的入口方法在 AMS 的 systemReady 方法中,首先会通过意图向 PMS 发起解析请求,PMS 查询返回 ActivityInfo 对象,注意这里的 category 是 CATEGORY_HOME ;然后通过进程的名字和 uid 去查询是否启动了进程,目前 Launcher 进程的 ProcessRecord 肯定是空;最后调用 startHomeActivity 方法去启动和创建 Launcher

流程图:

  • 触发点ActivityManagerService.systemReady()

  • 核心逻辑

    scss 复制代码
    // AMS.java
    void systemReady() {
      // 1. 通过Intent.CATEGORY_HOME查找Launcher
      Intent intent = new Intent(Intent.ACTION_MAIN);
      intent.addCategory(Intent.CATEGORY_HOME);
      ResolveInfo info = mPackageManager.resolveActivity(intent);
      
      // 2. 启动Launcher进程
      mStackSupervisor.startHomeActivity(intent, info, "systemReady");
    }
  • 桌面初始化

    Launcher通过PMS查询所有应用信息,生成图标列表(RecyclerView实现)

Launcher 是 Android 系统的桌面应用,负责展示所有安装的应用图标并管理用户交互。其启动流程涉及多个系统服务协同工作,以下是基于 Android 12 源码的完整分析:


5.1、启动触发时机

当 SystemServer 完成核心服务初始化后,通过 AMS 触发:

csharp 复制代码
// ActivityManagerService.java
public void systemReady() {
    mStackSupervisor.startHomeActivity(mCurrentUserId, "systemReady");
}

5.2 、核心流程(6 大关键步骤)
5.2.1. AMS 发起启动请求
scss 复制代码
// ActivityStackSupervisor.java
void startHomeActivity() {
    // 构造 HOME Intent
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK);
    
    // 查询符合条件的 Activity
    ActivityInfo aInfo = resolveActivity(intent);
    
    // 启动 Launcher
    mRootActivityContainer.startHomeActivity(intent, aInfo, "startHomeActivity");
}

启动时机

  • 触发点:ActivityManagerService.systemReady()
  • 调用链:SystemServer.run()AMS.systemReady()startHomeActivityLocked()
5.2.2. PMS 解析桌面应用
  • 源码路径PackageManagerService.java

  • 关键操作

    scss 复制代码
    public ResolveInfo resolveIntent(Intent intent, ...) {
        // 查询 AndroidManifest 中声明 CATEGORY_HOME 的 Activity
        List<ResolveInfo> query = queryIntentActivitiesInternal(...);
        return getDefaultHomeActivity(query, userId); // 选择优先级最高的
    }
  • 选择逻辑

    1. 系统预置 Launcher(packages/apps/Launcher3
    2. 第三方桌面(如 Nova Launcher)
    3. 优先级由 <intent-filter>priority 决定
5.2.3. Zygote 孵化进程

Launcher如何通知Zygote创建APP?

  • 用户点击图标 → Launcher通过Binder调用AMS的startActivity()
  • AMS通过Socket通知Zygote → Zygote执行fork()创建新进程
  • 子进程执行ActivityThread.main() → 创建Application/Activity
arduino 复制代码
  
   // ActivityManagerService.java
    void startActivity() {
        // 通过Socket通信
        ProcessStartResult startResult = Process.start(entryPoint,
            app.processName, uid, gid, gids, runtimeFlags, mountExternal,
            app.info.targetSdkVersion, ...);
    }
  • 进程创建

    arduino 复制代码
    // ActivityManagerService.java
    final ProcessRecord startProcess(...) {
        // 通过 Socket 通知 Zygote
        Process.ProcessStartResult startResult = Process.start(...);
    }
  • 参数传递

    ini 复制代码
    --runtime-args=--package=com.android.launcher3
    --target-sdk-version=31
    --application-info=...

Launcher进程和system_server进程实现通信的线程:

Android系统启动的最后一步是启动一个Home应用程序,这个应用程序用来显示系统中已经安装的应用程序,这个Home应用程序就叫做Launcher。应用程序Launcher在启动过程中会请求PackageManagerService返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标来启动相应的应用程序。

5.2.4. Launcher 进程初始化
  • 入口函数ActivityThread.main()

    arduino 复制代码
    public static void main(String[] args) {
        Looper.prepareMainLooper(); // 主线程消息循环
        ActivityThread thread = new ActivityThread();
        thread.attach(false); // 绑定到 AMS
        Looper.loop();
    }
  • 关键调用链
    ActivityThread.attach()AMS.attachApplication()realStartActivityLocked()

5.2.5. Launcher 界面初始化
  • 源码路径Launcher.java

    scss 复制代码
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 1. 加载布局
        setContentView(R.layout.launcher);
        
        // 2. 初始化核心组件
        mWorkspace = findViewById(R.id.workspace); // 桌面页容器
        mAppDrawer = findViewById(R.id.apps_view); // 应用抽屉
        
        // 3. 绑定数据
        mModel.startLoader(); // 触发应用图标加载
    }
5.2.6. 应用图标加载
  • 数据来源LauncherModel.java

    scss 复制代码
    public void startLoader() {
        // 通过 PMS 获取所有应用
        List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(...);
        
        // 更新 UI(主线程)
        mUiExecutor.execute(() -> {
            mCallbacks.bindAllApplications(apps); // 回调 Launcher
        });
    }
  • 图标渲染

    javascript 复制代码
    // BubbleTextView.java
    void applyFromApplicationInfo(ApplicationInfo info) {
        setCompoundDrawablesRelativeWithIntrinsicBounds(
            info.iconBitmap, // PMS 封装的图标资源
            null, null, null
        );
    }

5.2.7. 系统如何找到桌面应用

  • PMS扫描所有APK的AndroidManifest.xml
  • 匹配包含CATEGORY_HOME的Activity:
ini 复制代码
   <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.HOME"/>
   </intent-filter>
  • 选择策略:取优先级最高(<priority>值最大)的应用

三、关键技术机制
1. 跨进程协作
服务 作用 通信方式
AMS 生命周期管理 Binder (IActivityManager)
PMS 提供应用列表和图标 Binder (IPackageManager)
WindowManager 窗口管理和事件分发 Binder (IWindowManager)

总结:

  1. 描述Android系统启动流程?

    markdown 复制代码
    `Boot ROM → Bootloader → Linux Kernel → init进程 → Zygote → SystemServer → AMS/PMS/WMS → Launcher`
    
    -   **Loader层**:Bootloader加载内核
    -   **Kernel层**:初始化驱动、启动swapper/kthreadd进程
    -   **Native层**:init进程挂载文件系统、启动Zygote/ServiceManager
    -   **Framework层**:Zygote孵化SystemServer,后者启动AMS等核心服务
    -   **App层**:AMS启动Launcher
  2. init进程的作用是什么?

    • 创建文件系统目录(如/dev/proc
    • 启动属性服务(property_service
    • 解析init.rc脚本,启动关键守护进程(Zygote、ServiceManager)16

🥚 二、Zygote机制

  1. 为什么system_server由Zygote启动而非init?

    • 核心答案 :Zygote通过预加载资源(JNI函数、共享库、类、主题),利用Copy-On-Write (COW) 机制让system_server直接继承资源,避免重复加载,加速启动。
  2. 为何用Zygote孵化App进程而非SystemServer?

    • 关键点

      • SystemServer已启动AMS/WMS等80+个服务,而App进程不需要这些;
      • SystemServer多线程环境,fork时易引发死锁(见下文详解)。
  3. Zygote为何用Socket而非Binder通信?

    • 本质矛盾:Binder依赖多线程池,而fork时仅复制当前线程。若Zygote使用Binder:

      • 子进程可能继承未释放的锁 → 死锁风险
      • Socket单线程模型更安全,且fork后子进程可独立启动Binder线程池。

⚙️ 三、SystemServer与Binder

  1. SystemServer、ServiceManager、SystemServiceManager的关系?

    • 三角关系

      • SystemServiceManager(在SystemServer内):管理系统服务生命周期(如AMS/PMS的启动)38;
      • ServiceManager (独立进程):Binder服务的"路由表",通过addService()/getService()注册与查询服务38;
      • SystemServer将服务Binder注册到ServiceManager供全局访问8。
  2. ServiceManager何时启动?由谁启动?

    • :由init进程 解析init.rc时启动,早于Zygote,是Binder IPC的基石。

⚠️ 四、高级原理

  1. 多线程环境下fork为何会导致死锁?

    • 场景还原
      父进程线程A持有锁L → fork时仅复制当前线程B → 子进程中线程A"消失",锁L无人释放 → 子进程线程B尝试获取锁L → 永久死锁47。
    • Zygote的解决方案:fork前主动停止非必要线程,fork后重启。
  2. Zygote预加载了哪些资源?

    • 常用类(preloadClasses(),约2000+个)
    • 资源(drawable/color等)
    • 共享库(libandroid.so、OpenGL)
    • 字体25。
  3. binder进程是在什么时候初始化的? Binder初始化时机

    • Init进程启动servicemanager
    • SystemServer中启动Binder线程池
    • 应用进程继承自Zygote

Binder线程池启动

  • 位置:RuntimeInit.nativeFinishInit() (JNI)

  • 关键代码:

    scss 复制代码
    // AndroidRuntime.cpp
    void startReg() {
        ProcessState::self()->startThreadPool(); // 启动Binder线程池
    }
相关推荐
Silver〄line几秒前
以鼠标位置为中心进行滚动缩放
前端
LaiYoung_2 分钟前
深入解析 single-spa 微前端框架核心原理
前端·javascript·面试
Danny_FD1 小时前
Vue2 + Node.js 快速实现带心跳检测与自动重连的 WebSocket 案例
前端
uhakadotcom1 小时前
将next.js的分享到twitter.com之中时,如何更新分享卡片上的图片?
前端·javascript·面试
韦小勇1 小时前
el-table 父子数据层级嵌套表格
前端
奔赴_向往1 小时前
为什么 PWA 至今没能「掘进」主流?
前端
小小愿望1 小时前
微信小程序开发实战:图片转 Base64 全解析
前端·微信小程序
掘金安东尼1 小时前
2分钟创建一个“不依赖任何外部库”的粒子动画背景
前端·面试·canvas
电商API大数据接口开发Cris1 小时前
基于 Flink 的淘宝实时数据管道设计:商品详情流式处理与异构存储
前端·数据挖掘·api
小小愿望1 小时前
解锁前端新技能:让JavaScript与CSS变量共舞
前端·javascript·css