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启动后会将已安装应用的快捷图标显示到界面上。
-
核心流程:
- PMS解析
CATEGORY_HOME
应用 - Zygote孵化Launcher进程
- 加载应用图标(通过PMS获取数据)
- 渲染桌面UI
- PMS解析
系统进程的启动顺序:
Init进程-->Zygote进程-->SystemServer进程-->应用进程(Launcher)


其他: 开机动画控制机制: 和launcher关系
-
启动流程
csharp// SurfaceFlinger.cpp void startBootAnim() { property_set("service.bootanim.exit", "0"); property_set("ctl.start", "bootanim"); // 触发init启动服务 }
-
关闭条件
scss// BootAnimation.cpp void checkExit() { property_get("service.bootanim.exit", value, "0"); if (atoi(value)) requestExit(); // AMS通知退出 }
-
自定义动画
-
替换路径:
/system/media/bootanimation.zip
-
制作规范:
desc.txt
:定义分辨率/帧率part0/
:首帧图片序列part1/
:循环帧序列
-
2. Init进程(用户空间第一个进程)
流程图:

-
源码路径 :
system/core/init/init.cpp
-
核心任务:
scssint 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 配置项):
cclass 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
-
- 启动SystemServer进程。
-
- 创建jni startReg()
- 4.预加载资源
最后再来总结一下:
Zygote 进程是由 init 进程解析 init.rc 脚本创建的,其具体的执行源码是在 App_main.main 方法,
首先会创建一个虚拟机实例,然后注册 JNI 方法,最后通过 JNI 调用进入 Java 世界来到 ZygoteInit.main 方法。
在 Java 世界中我们会为 Zygote 注册 socket 用于进程间通信,预加载一些通用的类和资源,
启动 system_server 进程,循环等待孵化创建新的进程。
完整的4步骤:
1.创建虚拟机, 启动虚拟机VM startVm();
- 创建jni, startReg()
2.预加载资源
3.循环等待孵化创建新的进程
Zygote 最后是一个死循环,不断的等待远程跟我通信,创建子进程 ,Os.poll(pollFds, -1); 会阻塞等待有没有新的文件描述符发生变化
4.启动SystemServer进程。
- 创建 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 创建:
scssprivate 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()
创建。 -
关键服务初始化顺序:
-
引导服务:
ActivityManagerService (AMS)
:应用生命周期管理。PowerManagerService (PMS)
:电源管理。PackageManagerService (PMS)
:应用包管理。
-
核心服务:
WindowManagerService (WMS)
:窗口管理、输入事件分发。DisplayManagerService
:显示管理。
-
其他服务 :
AudioService
、SensorService
等。
-
-
服务注册 :所有服务通过
ServiceManager.addService()
注册 Binder 接口(例如AMS
注册为activity
)。
SystemServer 是 Android 系统的核心进程,承载了所有关键系统服务(如 AMS、PMS、WMS)。其启动与运行机制如下:
4.1、创建过程(由 Zygote 进程 fork 完成)
-
启动触发
- Zygote 启动时通过
--start-system-server
参数触发 SystemServer 的创建。 - 在
ZygoteInit.main()
中解析参数并调用 `forkSystemServer()。
- Zygote 启动时通过
-
参数配置
SystemServer 的启动参数硬编码在
startSystemServer()
中,包括:arduinoString 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]
-
进程 fork
- 调用
Zygote.forkSystemServer()
→ JNI 层nativeForkSystemServer()
→ 最终执行ForkAndSpecializeCommon()
67。 - 关键机制 :Zygote 通过
waitpid()
监控 SystemServer 状态,若其异常退出会重启 Zygote。
- 调用
4.2、初始化流程(在 SystemServer 进程内执行)
-
环境准备
- 关闭从 Zygote 继承的 Socket(仅 Zygote 需监听请求。
- 调用
RuntimeInit.zygoteInit()
初始化通用环境(时区、日志等)。
-
启动 Binder 通信
-
通过 JNI 调用
onZygoteInit()
→ 启动 Binder 线程池:rubysp<ProcessState> proc = ProcessState::self(); proc->startThreadPool(); // 启动 Binder IPC 线程池:cite[3]:cite[4]
-
-
执行 SystemServer.main()
-
通过反射调用
com.android.server.SystemServer.main()
。 -
入口方法核心步骤:
typescriptpublic static void main(String[] args) { System.loadLibrary("android_servers"); // 加载 JNI 库 run(); // 调用 SystemServer.run() } :cite[3]:cite[6]
-
4.3 、核心服务启动(SystemServer.run()
)
-
基础初始化
- 创建主线程 Looper、系统上下文(
SystemContext
)、SystemServiceManager
。
- 创建主线程 Looper、系统上下文(
-
分阶段启动服务
阶段 服务示例 作用 Bootstrap ActivityManagerService
(AMS)应用生命周期管理 PowerManagerService
电源管理 Core BatteryService
电池状态监控 UsageStatsService
应用使用统计 Other WindowManagerService
(WMS)窗口管理与事件分发 PackageManagerService
(PMS)应用安装与权限管理16 -
服务依赖管理
- AMS 最先启动,因其是其他服务(如 PMS)的依赖基础6。
- 所有服务通过
ServiceManager.addService()
注册 Binder 接口,供应用调用。
-
启动完成回调
调用
ActivityManagerService.systemReady()
,触发 Launcher 启动。
4.4 、SystemServer 的核心地位
- 系统服务容器
90% 的系统服务(如 BluetoothService、SensorService)以线程形式运行其中。 - 安全隔离层
应用进程无直接硬件访问权限,必须通过 SystemServer 的 Binder 代理操作设备。 - 生死监控(Watchdog)
内置看门狗模块,检测服务线程死锁,超时则重启系统。
4.5 、关键设计机制
-
与 Zygote 的生死绑定
- SystemServer 崩溃会导致 Zygote 自杀重启(通过
waitpid()
监控实现)。
- SystemServer 崩溃会导致 Zygote 自杀重启(通过
-
延迟服务加载
非关键服务(如蓝牙)按需启动,减少开机时间6。
-
主线程事件循环
通过
Looper.loop()
监听 Binder 调用与系统事件。
4.6 、典型问题分析
-
为何 SystemServer 不直接由 init 启动?
- 需复用 Zygote 预加载的 Java 环境(类/资源),避免重复初始化。
-
系统卡顿与 SystemServer 的关系?
- Watchdog 超时或 Binder 线程池阻塞会导致 ANR,甚至系统重启。
-
开机优化方向
- 减少
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
-
关键操作:
scsspublic ResolveInfo resolveIntent(Intent intent, ...) { // 查询 AndroidManifest 中声明 CATEGORY_HOME 的 Activity List<ResolveInfo> query = queryIntentActivitiesInternal(...); return getDefaultHomeActivity(query, userId); // 选择优先级最高的 }
-
选择逻辑:
- 系统预置 Launcher(
packages/apps/Launcher3
) - 第三方桌面(如 Nova Launcher)
- 优先级由
<intent-filter>
的priority
决定
- 系统预置 Launcher(
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()
arduinopublic 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
scssprotected 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
scsspublic 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) |
总结:
-
描述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
-
init进程的作用是什么?
- 创建文件系统目录(如
/dev
、/proc
) - 启动属性服务(
property_service
) - 解析
init.rc
脚本,启动关键守护进程(Zygote、ServiceManager)16
- 创建文件系统目录(如
🥚 二、Zygote机制
-
为什么system_server由Zygote启动而非init?
- 核心答案 :Zygote通过预加载资源(JNI函数、共享库、类、主题),利用Copy-On-Write (COW) 机制让system_server直接继承资源,避免重复加载,加速启动。
-
为何用Zygote孵化App进程而非SystemServer?
-
关键点:
- SystemServer已启动AMS/WMS等80+个服务,而App进程不需要这些;
- SystemServer多线程环境,fork时易引发死锁(见下文详解)。
-
-
Zygote为何用Socket而非Binder通信?
-
本质矛盾:Binder依赖多线程池,而fork时仅复制当前线程。若Zygote使用Binder:
- 子进程可能继承未释放的锁 → 死锁风险;
- Socket单线程模型更安全,且fork后子进程可独立启动Binder线程池。
-
⚙️ 三、SystemServer与Binder
-
SystemServer、ServiceManager、SystemServiceManager的关系?
-
三角关系:
- SystemServiceManager(在SystemServer内):管理系统服务生命周期(如AMS/PMS的启动)38;
- ServiceManager (独立进程):Binder服务的"路由表",通过
addService()
/getService()
注册与查询服务38; - SystemServer将服务Binder注册到ServiceManager供全局访问8。
-
-
ServiceManager何时启动?由谁启动?
- :由init进程 解析
init.rc
时启动,早于Zygote,是Binder IPC的基石。
- :由init进程 解析

⚠️ 四、高级原理
-
多线程环境下fork为何会导致死锁?
- 场景还原 :
父进程线程A持有锁L → fork时仅复制当前线程B → 子进程中线程A"消失",锁L无人释放 → 子进程线程B尝试获取锁L → 永久死锁47。 - Zygote的解决方案:fork前主动停止非必要线程,fork后重启。
- 场景还原 :
-
Zygote预加载了哪些资源?
- 常用类(
preloadClasses()
,约2000+个) - 资源(drawable/color等)
- 共享库(
libandroid.so
、OpenGL) - 字体25。
- 常用类(
-
binder进程是在什么时候初始化的? Binder初始化时机:
- Init进程启动
servicemanager
- SystemServer中启动Binder线程池
- 应用进程继承自Zygote
- Init进程启动
Binder线程池启动
-
位置:
RuntimeInit.nativeFinishInit()
(JNI) -
关键代码:
scss// AndroidRuntime.cpp void startReg() { ProcessState::self()->startThreadPool(); // 启动Binder线程池 }