在启动 Activity 时,如果 ATMS 发现目标进程(ProcessRecord)不存在,就会触发进程创建流程。这是 Android 系统中典型的“按需启动”机制。
1. 触发点:AMS.startProcessLocked
当 ATMS 判定需要新进程来承载 Activity 时,会跨模块回调 AMS:
1 | // 核心逻辑简述 |
2. AMS 与 Zygote 的通信流程表
| 阶段 | 核心方法 | 动作描述 |
|---|---|---|
| 1. 决策 | startProcessLocked |
AMS 确定进程参数(UID, GID, 启动类 ActivityThread)。 |
| 2. 发起请求 | Process.start |
通过 ZygoteProcess 建立与 Zygote 的 Socket 连接。 |
| 3. 通信 | ZygoteState.connect |
向 /dev/socket/zygote 写入启动参数字符串。 |
| 4. 孵化 | Zygote.fork() |
Zygote 接收信号,Fork 自身进程(利用 COW 机制)。 |
| 5. 诞生 | RuntimeInit |
子进程初始化运行环境,并抛出 MethodAndArgsCaller 异常以进入 Java 入口。 |
3. 为什么是 Socket 而不是 Binder?
这是一个经典考点。Zygote 使用 LocalSocket 监听请求而非 Binder,主要是为了规避 Fork 机制与多线程锁冲突 导致的死锁风险。在 fork 瞬间,子进程只会拷贝发起调用的线程,其他线程持有的锁将永远无法在子进程中释放。
4. 子进程的“觉醒”:ActivityThread.main()
当 fork 成功后,子进程会执行 ActivityThread.main() 方法,这标志着应用主线程正式开始工作:
- **Looper.prepareMainLooper()**:初始化主线程消息循环。
- attach:跨进程向 AMS 报告:“我启动好了(
attachApplication)”。 - BIND_APPLICATION:AMS 发回应用配置信息,App 开始创建
Application实例并调用onCreate。 - **Looper.loop()**:主线程进入死循环,开始处理 AMS 发来的生命周期指令(如
LAUNCH_ACTIVITY)。
5. 总结
进程创建是一个“从 C++ 到 Java”的过程,也是“从系统服务到应用代码”的过程。掌握了从 startProcessLocked 到 attachApplication 的闭环,就掌握了 Android 进程管理的精髓。