app 启动流程
Android 应用启动流程(从点击桌面图标到主 Activity 显示)主要涉及 Launcher 、System Server(AMS) 、Zygote 进程 以及 应用进程 之间的协作。整体可分为两大阶段:进程创建 和 组件初始化。
一、整体流程概览
text
用户点击图标
↓
Launcher 通知 AMS 启动 Activity
↓
AMS 检查进程是否存在 → 若不存在,请求 Zygote 创建新进程
↓
Zygote fork 出应用进程
↓
应用进程初始化(ActivityThread、Application)
↓
AMS 通知应用进程创建 Activity
↓
应用执行 Activity 生命周期(onCreate → onStart → onResume)
↓
视图渲染并显示
二、详细步骤分解
1. 用户点击图标 → Launcher 处理
- Launcher 本身是一个
Activity,其图标点击通过startActivity()发起启动请求。 - 调用
Instrumentation.execStartActivity(),通过 Binder 通信将请求发送给 ActivityManagerService (AMS) 。
2. AMS 处理启动请求
-
AMS 收到
startActivity请求后,进行:- 解析 Intent(目标 Activity、启动模式等)
- 检查权限、启动标志
- 根据
AndroidManifest.xml确定目标 Activity 所属的进程名
-
AMS 调用
ActivityStackSupervisor.startActivitySpecificLocked()→ActivityStack.resumeTopActivityInnerLocked()等内部逻辑。
3. 判断应用进程是否存在
- AMS 调用
ProcessRecord getProcessRecordLocked()查找该应用是否已有运行中的进程。 - 如果进程不存在(冷启动),执行 进程创建;
- 如果进程已存在(热启动/温启动),则直接通知进程创建 Activity(跳到步骤6)。
4. 创建应用进程(冷启动)
- AMS 通过 Socket 向 Zygote 进程 发送
fork请求。 - Zygote 进程 fork 自身,生成新的应用进程。
- 新进程获得 Zygote 预先加载的共享类、资源、JNI 等,加速启动。
- 新进程启动后,调用
ActivityThread.main()(应用入口)。
5. 应用进程初始化
-
ActivityThread.main()执行:- 准备主线程
Looper - 创建
ActivityThread实例,调用attach(false)将自己绑定到 AMS(通过 Binder) - 进入
Looper.loop(),开始处理来自 AMS 的消息
- 准备主线程
-
AMS 收到绑定后,通过
ApplicationThread(Binder 接口)回调应用进程,要求创建Application对象。- 调用
Instrumentation.newApplication()→makeApplication()→Application.onCreate()
- 调用
6. 创建目标 Activity
-
AMS 向应用进程发送
LAUNCH_ACTIVITY事务(通过ApplicationThread.scheduleLaunchActivity)。 -
主线程 Handler 接收到消息,调用
ActivityThread.handleLaunchActivity():-
performLaunchActivity():- 通过
ClassLoader创建 Activity 实例 - 调用
attach()关联Window、WindowManager等 - 调用
Instrumentation.callActivityOnCreate()→Activity.onCreate() - 执行
setContentView()加载布局 → 完成 View 树的创建
- 通过
-
handleResumeActivity():Activity.onStart()Activity.onResume()- 将
DecorView添加到WindowManager,触发 ViewRootImpl,开始测量/布局/绘制
-
-
最终 Activity 的内容显示到屏幕上。
三、关键进程与组件
| 角色 | 职责 |
|---|---|
| Launcher | 入口触发 startActivity,运行在系统桌面进程 |
| System Server | 包含 AMS、WMS、PMS 等系统服务,管理应用生命周期 |
| Zygote | 预加载类/资源,快速 fork 应用进程 |
| 应用进程 | 运行 Activity、Service 等组件,主线程处理 UI 及 AMS 回调 |
| ActivityThread | 应用主线程入口,管理 Activity、接收 AMS 指令 |
| Instrumentation | 监控应用与系统的交互,如启动 Activity、生命周期回调 |
四、冷启动 vs 热启动 vs 温启动
- 冷启动:进程不存在,需要创建进程 → 流程完整,耗时最长(常见于首次启动或被系统杀死后)。
- 热启动 :进程和 Activity 都还在后台,只需从
onStop恢复(不经过 onCreate)。 - 温启动:进程存在但 Activity 被销毁(如内存不足重建),需要重新创建 Activity(走步骤6)。
五、流程图(简化)
text
Launcher
│ (Binder: startActivity)
▼
AMS (System Server)
│ 判断进程是否存在
│ ─── 不存在 ──→ Socket ──→ Zygote ──fork──→ 新应用进程
│ │ ActivityThread.main()
│ │ ──attach──→ AMS
│ ←─────────────────────────────────────────┤
│ (Binder: scheduleLaunchActivity)
▼
应用进程主线程
│ ActivityThread.handleLaunchActivity()
│ ├─ 创建 Activity 实例
│ ├─ onCreate() → setContentView()
│ ├─ onStart()
│ └─ onResume()
└─ WindowManager.addView() → ViewRootImpl → 显示
六、常见优化点(冷启动)
- 避免在
Application.onCreate()和Activity.onCreate()中做耗时操作。 - 使用
SplashScreen(Android 12+ API 或自定义)提升感知速度。 - 减少布局层级,延迟加载非必要组件。
- 利用
ViewStub、AsyncLayoutInflater等。