一、引言:为什么要搞懂 Android 开机流程?
你有没有遇到过这些问题:
- App 冷启动为什么慢?和系统启动有没有关系?
- 为什么有些系统服务可以在开机自启,而你的不行?
- 系统卡在开机动画(boot animation)时,到底卡在哪一步?
- 如何通过 hook / 插桩分析系统服务启动顺序?
👉 本质上,这些问题都指向一个核心:Android 系统是如何“从 0 到 1”运行起来的。
理解开机流程,不仅仅是系统工程师的专属能力,对于中高级 Android 开发来说,它能帮你:
- 更深入理解 AMS / PMS / Zygote 等核心机制
- 优化 App 启动链路
- 排查系统级问题(ANR / 卡顿 / 死锁)
- 为 Framework 层开发打基础
二、背景知识:你需要提前知道什么?
在深入之前,先快速过一遍几个关键角色:
| 组件 | 作用 |
|---|---|
| Bootloader | 启动内核 |
| Linux Kernel | 启动系统基础环境 |
| init 进程 | Android 用户空间的“1号进程” |
| Zygote | 应用进程孵化器 |
| SystemServer | 启动所有系统服务(AMS / PMS 等) |
👉 可以简单理解为:
硬件 → Bootloader → Kernel → init → Zygote → SystemServer → Launcher
三、核心原理解析:开机全过程(主线梳理)
我们从按下电源键开始,一步步看:
1️⃣ Bootloader:系统启动的第一步
- 负责初始化硬件(CPU / 内存)
- 加载 Linux Kernel
- 校验系统完整性(Verified Boot)
👉 类比:就像 BIOS / UEFI
2️⃣ Linux Kernel:内核启动
Kernel 完成:
- 初始化驱动(显示、输入设备等)
- 挂载 root 文件系统
- 启动第一个用户进程:
init
3️⃣ init 进程:Android 世界的起点
init 是 用户空间第一个进程(PID = 1)
它的核心职责:
- 解析
.rc配置文件(init.rc) - 启动关键服务
- 设置权限 / SELinux
- 启动 Zygote
关键代码(简化):
int main(int argc, char** argv) {
init_parse_config_file("/init.rc");
start_property_service();
service_start("zygote");
}
👉 重点:所有系统服务的“启动指令”都来自 init.rc
4️⃣ Zygote:应用进程孵化器
Zygote 是 Android 进程模型的核心。
它做了三件事:
- 启动 JVM(ART)
- 预加载类和资源
- 通过 fork 创建新进程
public static void main(String[] argv) {
preloadClasses();
preloadResources();
startSystemServer();
}
👉 为什么要用 Zygote?
- fork 比创建进程更快
- 共享内存(减少内存占用)
5️⃣ SystemServer:系统服务启动核心
这是最关键的一步。
Zygote fork 出 SystemServer 进程后:
private static void startBootstrapServices() {
mActivityManagerService = ActivityManagerService.startService();
mPackageManagerService = PackageManagerService.main();
}
SystemServer 会启动:
- ActivityManagerService(AMS)
- PackageManagerService(PMS)
- WindowManagerService(WMS)
- PowerManagerService 等
👉 一句话总结:SystemServer = Android 的“大脑”
6️⃣ Launcher 启动:用户终于看到桌面
AMS 启动后,会执行:
startHomeActivityLocked()
本质是:
- 找到 HOME Intent
- 启动 Launcher App
val intent = Intent(Intent.ACTION_MAIN).apply {
addCategory(Intent.CATEGORY_HOME)
}
startActivity(intent)
👉 到这里,用户看到桌面,开机流程结束。
四、源码关键链路(精简版)
完整调用链(建议收藏):
Bootloader
↓
Linux Kernel
↓
init
↓
ZygoteInit.main()
↓
fork SystemServer
↓
SystemServer.main()
↓
startBootstrapServices()
↓
startOtherServices()
↓
AMS.startHomeActivityLocked()
↓
Launcher
五、实战示例:监听“系统启动完成”
很多业务需要:
👉 开机后自动执行任务(比如埋点 / 预加载)
方案:监听 BOOT_COMPLETED
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application>
<receiver
android:name=".BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
Log.d("BootReceiver", "System boot completed")
}
}
}
⚠️ 注意:
- Android 8.0+ 有后台限制
- 某些 ROM 会限制自启动
六、常见误区 / 踩坑总结
❌ 误区 1:BOOT_COMPLETED 一定会触发
👉 错!
- 用户首次解锁前不会发(Direct Boot 机制)
- 厂商可能拦截
❌ 误区 2:所有服务都在 SystemServer 启动
👉 错!
- 一些 Native 服务在 init 阶段启动
- HAL 层不在 Java 世界
❌ 误区 3:Zygote 只启动一次
👉 不完全对:
- 有 Zygote64 / Zygote32
- 多进程模型存在多个 Zygote
七、性能优化 & 最佳实践
🚀 1. 减少冷启动依赖 SystemServer
- 不要在 Application.onCreate 做重逻辑
- 延迟初始化(Lazy)
🚀 2. 利用 ContentProvider 提前初始化
class InitProvider : ContentProvider() {
override fun onCreate(): Boolean {
initSDK()
return true
}
}
👉 它在 Application 之前执行
🚀 3. 分析启动链路(强烈推荐)
工具:
- Systrace
- Perfetto
- Logcat(关键 tag)
重点关注:
- AMS 启动耗时
- PMS 扫描 APK 时间
🚀 4. Hook SystemService(进阶)
在 Framework 开发中:
- 可以插桩 AMS / PMS
- 分析服务启动顺序
八、总结:一张图看懂 Android 开机
电源键
↓
Bootloader
↓
Kernel
↓
init(解析 rc)
↓
Zygote(预加载 + fork)
↓
SystemServer(启动 AMS/PMS)
↓
Launcher
↓
用户可交互
最后一句话总结
👉 Android 开机本质是:从 init 启动 Zygote,再由 Zygote 孵化 SystemServer,最终启动整个 Java 世界。