App 启动流程
问题
从点击桌面图标到 Activity 显示,经历了哪些步骤?
答案
完整启动流程
关键阶段
阶段一:进程创建(冷启动才有)
- Launcher 通过 Binder 调用 AMS 的
startActivity - AMS 发现目标 App 进程不存在,通过 Socket 通知 Zygote
- Zygote
fork()出新进程(继承了 Android Runtime、预加载的类和资源) - 新进程调用
ActivityThread.main(),创建主线程 Looper
阶段二:Application 初始化
ActivityThread通过 Binder 调用 AMS 的attachApplication- AMS 回调
bindApplication,触发Application.attachBaseContext()→Application.onCreate()
阶段三:Activity 创建与显示
- AMS 告知 App 启动目标 Activity
- 创建 Activity 实例,依次回调
onCreate→onStart→onResume WindowManager.addView()添加 DecorView- Choreographer 接收 VSync 信号,执行 measure → layout → draw,首帧渲染完成
冷启动 vs 温启动 vs 热启动
| 类型 | 进程状态 | Activity 状态 | 性能 |
|---|---|---|---|
| 冷启动 | 不存在 | 不存在 | 最慢 |
| 温启动 | 存在 | 被销毁 | 中等 |
| 热启动 | 存在 | 在后台 | 最快 |
常见面试问题
Q1: Zygote fork 进程有什么优势?
答案:
Zygote 在启动时已经加载了 Android Framework 的核心类(约 4000+ 个类)和共享资源。fork 出的子进程通过**写时复制(Copy-on-Write)**共享这些内存页,不需要重新加载。这使得 App 进程启动远快于从零开始。
Q2: Application.onCreate 为什么不能做太多耗时操作?
答案:
Application.onCreate() 在主线程执行,处于冷启动的关键路径上。此时用户看到的是白屏(或 SplashScreen),任何耗时操作都会延长白屏时间。SDK 初始化、数据预加载等应按需延迟到 Activity 之后或使用 App Startup 库异步初始化。