Activity 启动之进程创建流程(AMS 与 Zygote 的握手)

在启动 Activity 时,如果 ATMS 发现目标进程(ProcessRecord)不存在,就会触发进程创建流程。这是 Android 系统中典型的“按需启动”机制。

1. 触发点:AMS.startProcessLocked

当 ATMS 判定需要新进程来承载 Activity 时,会跨模块回调 AMS:

1
2
3
4
5
// 核心逻辑简述
if (app == null) {
// 进程不存在,开始启动进程
mService.startProcessLocked(processName, info, ...);
}

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() 方法,这标志着应用主线程正式开始工作:

  1. **Looper.prepareMainLooper()**:初始化主线程消息循环。
  2. attach:跨进程向 AMS 报告:“我启动好了(attachApplication)”。
  3. BIND_APPLICATION:AMS 发回应用配置信息,App 开始创建 Application 实例并调用 onCreate
  4. **Looper.loop()**:主线程进入死循环,开始处理 AMS 发来的生命周期指令(如 LAUNCH_ACTIVITY)。

5. 总结

进程创建是一个“从 C++ 到 Java”的过程,也是“从系统服务到应用代码”的过程。掌握了从 startProcessLockedattachApplication 的闭环,就掌握了 Android 进程管理的精髓。

, ,