2. Android系统架构与启动流程
理解 Android 的性能与稳定性问题,必须先理解系统从上电到桌面可交互之间发生了什么。Android 的启动不是“内核启动完就结束”,而是一条由 init → Zygote → SystemServer → 核心系统服务 → Launcher 组成的链式过程。链上任意一环变慢,都会直接体现为开机时间变长、首屏卡顿甚至开机失败。本章聚焦这条链的结构、启动顺序与性能关键路径。
一、核心原理:分层架构与启动链
Android 系统架构自下而上可分为:Linux 内核层、硬件抽象层(HAL)、原生库与运行时(含 ART)、Java API 框架层、应用层。启动流程正是自下而上逐层“点亮”的过程:内核启动后挂载根文件系统并执行 init,init 解析 init.rc 启动各类 native 服务,其中最关键的是 servicemanager、zygote 与 surfaceflinger。
Zygote 是 Android 应用进程的“母体”。它在启动时预加载大量常用类与资源,并初始化 ART 虚拟机,随后进入 socket 循环等待孵化请求。当需要启动新应用进程时,AMS 通过 socket 通知 Zygote,Zygote 以 fork() 方式复制自身,子进程再执行 RuntimeInit 与 ActivityThread.main()。这种“预加载 + fork”的设计大幅缩短了应用启动时间,也是 Android 区别于传统 Linux 进程模型的关键。
SystemServer 是 Java 框架层的起点,由 Zygote fork 出的第一个 Java 进程。它按严格顺序启动上百个系统服务,其中 AMS(ActivityManagerService)、PMS(PackageManagerService)、WMS(WindowManagerService)是三大核心。AMS 负责进程与四大组件调度,PMS 负责包解析与权限,WMS 负责窗口与输入分发。它们之间存在强依赖:AMS 启动时需要 PMS 提供包信息,WMS 又依赖 AMS 的进程管理能力。
二、方法流程:核心服务启动顺序
SystemServer 的启动顺序经过精心设计,遵循“先底层后上层、先基础后业务”的原则。其 run() 方法中依次调用 startBootstrapServices()、startCoreServices()、startOtherServices()。关键顺序如下:
- 引导服务:ActivityManagerService、PowerManagerService、PackageManagerService、DisplayManagerService 等。AMS 与 PMS 在此阶段创建,PMS 会扫描
/system/framework、/data/app等目录下的 APK,解析 AndroidManifest,构建包信息数据库。 - 核心服务:BatteryService、UsageStatsService、WebViewUpdateService 等。
- 其他服务:WindowManagerService、InputManagerService、NetworkManagementService、MountService 等。WMS 在此时完成窗口层级与输入通道的建立。
- 系统就绪:所有服务启动完毕后,AMS 调用
systemReady(),通知各服务进入运行态,随后启动 Launcher。
可以用以下命令观察启动各阶段耗时:
# 查看启动阶段时间戳
adb shell dmesg | grep -i "init\|zygote\|system_server"
# 查看 SystemServer 各服务启动耗时
adb logcat -b events | grep "system_server"
# 查看开机时间统计
adb shell "cat /proc/boottime" 2>/dev/null
adb shell dumpsys activity | grep -i "boot"
三、案例/场景:首屏卡顿的定位
某项目反馈“开机后桌面出现慢、点击图标无响应”。排查思路如下:
- 用
adb shell dumpsys activity activities查看 Launcher 是否已处于 RESUMED 状态,若长时间停留在 STARTING,说明 AMS 调度或进程创建受阻。 - 用
adb shell dumpsys window检查 WMS 是否已完成窗口添加,若mCurrentFocus为空,说明窗口尚未就绪。 - 用
adb shell dumpsys package观察 PMS 扫描耗时,若 APK 数量多或存在损坏包,PMS 会阻塞后续服务。 - 用
adb shell top -H观察 system_server 线程 CPU 占用,定位是否在PackageManagerService或ActivityManagerService初始化中空转。
最终定位为 PMS 扫描某个第三方预装 APK 时解析异常,导致启动链在引导服务阶段被拉长。移除该 APK 后开机时间从 28s 降至 19s。
四、误区与复盘
常见误区一:认为“开机慢就是内核慢”。实际上内核阶段通常只占 2~4 秒,大部分时间消耗在 Zygote 预加载、PMS 扫描与 SystemServer 服务初始化上。
常见误区二:把 AMS、PMS、WMS 当作完全独立模块。它们存在启动依赖:AMS 需要 PMS 提供包信息,WMS 需要 AMS 提供进程与 Activity 记录,修改任一服务的初始化逻辑都可能影响整条链。
常见误区三:只优化应用启动而不关注系统服务。若 SystemServer 尚未完成 systemReady(),应用进程即使被创建也无法正常显示。
| 阶段 | 关键对象 | 典型耗时 | 性能关注点 |
|---|---|---|---|
| 内核 / init | Kernel、init.rc | 2~4s | 驱动加载、分区挂载 |
| Zygote | 预加载类、ART | 1~3s | 预加载类数量、GC 策略 |
| SystemServer 引导 | AMS、PMS | 3~8s | APK 扫描、权限解析 |
| SystemServer 其他 | WMS、InputManager | 2~5s | 窗口层级、输入通道 |
| 应用层 | Launcher、首帧 | 1~3s | 首帧绘制、进程创建 |
优化启动链的核心思路:缩短关键路径上的串行耗时。例如减少 Zygote 预加载类、延迟非必要服务初始化、并行化 PMS 扫描、避免在 SystemServer 主线程做耗时 IO。任何在 systemReady() 之前执行的阻塞操作,都会直接转化为开机时间。