资讯动态

Android Framework源码解析(九):App进程诞生全流程——从AMS请求到Zygote fork源码深度拆解

发布时间:2026/8/18 13:08:52 来源:尧图企业网站定制
一、前文回顾 本章核心目标上一篇文章我们完整拆解了AMSActivityManagerService启动流程理清了Android高版本的核心架构分工ATMS专注任务栈管理、Activity启停与页面调度AMS专注进程管理、组件调度、内存管控、权限校验同时打通了startActivity完整跨进程链路 App端startActivity()→ Instrumentation中转 → Binder调用ATMS → ActivityStarter解析启动模式/任务栈 → 触发页面调度我们在文末留下了核心分支startSpecificActivity冷启动全新App时系统检测不到目标进程会进入分支由AMS发起进程创建请求。这就引出了Framework进阶核心问题App进程到底如何诞生AMS仅负责调度Zygote孵化器如何fork进程从进程创建到App初始化完成的完整底层链路是什么众所周知Android经典应用进程创建路径由Zygote fork生成。高版本Android引入了USAPUnspecialized App Process进程池优化机制会预创建闲置进程提升启动速度为突出核心底层原理本文以经典直接fork核心路径为主暂不展开USAP优化细节。Zygote如何接收system_server指令、如何依托Linux COW机制降低进程创建成本、如何初始化ART虚拟机与App运行上下文是Framework开发的核心难点。本篇将承接上文精简非核心分支、聚焦主流程层层拆解「AMS调度 → Zygote fork → App进程初始化 → Activity最终启动」全链路补齐Android应用启动的最后一块核心拼图。二、前置核心链路ATMS异步发起进程启动当冷启动App、目标进程不存在时ATMS会调用startProcessAsync()发起进程启动请求。为避免持有 ATMS 锁时同步调用 AMS 可能产生的锁竞争和死锁风险系统通过 Handler 异步投递进程启动请求。源码路径frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.javavoid startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop, String hostingType) { if (!mStartingProcessActivities.contains(activity)) { mStartingProcessActivities.add(activity); } else if (mProcessNames.get(activity.processName, activity.info.applicationInfo.uid) ! null) { return; } try { // 异步投递消息规避ATMS持锁调用AMS的死锁风险 final Message m PooledLambda.obtainMessage(ActivityManagerInternal::startProcess, mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead, isTop, hostingType, activity.intent.getComponent()); mH.sendMessage(m); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } }核心逻辑总结将待启动的Activity加入等待队列mStartingProcessActivities进程就绪后再唤醒启动通过Handler异步投递消息解除同步锁阻塞最终触发ActivityManagerInternal.startProcess()正式进入AMS进程启动逻辑。由此形成固定调用链路ATMS.startProcessAsync()→ 异步消息 →AMS.LocalService.startProcess()三、AMS核心调度委托ProcessList准备进程启动参数3.1 AMS入口方法源码路径frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javaAMS收到异步消息后通过内部服务调用startProcess()最终委托ProcessList处理进程启动核心逻辑ProcessList是Android系统进程管理的核心工具类。public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName) { try { synchronized (ActivityManagerService.this) { HostingRecord hostingRecord new HostingRecord(hostingType, hostingName, isTop); ProcessRecord rec getProcessRecordLocked(processName, info.uid); // 委托ProcessList执行进程启动逻辑 ProcessRecord app startProcessLocked(processName, info, knownToBeDead, 0, hostingRecord, ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false, false); } } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated) { // 转发至ProcessList核心方法 return mProcessList.startProcessLocked(...); }3.2 ProcessList进程启动参数全准备源码路径frameworks/base/services/core/java/com/android/server/am/ProcessList.javastartProcessLocked()是进程启动的核心准备入口会完成旧进程清理、权限校验、运行参数初始化等所有前置工作是Zygote fork前最关键的参数组装阶段。ProcessList 核心启动流程标准AOSP源码顺序ProcessList 的startProcessLocked()会按固定顺序完成进程启动全量前置准备摒弃零散冗余步骤核心流程如下创建/复用 ProcessRecord根据进程名、UID匹配或新建进程记录绑定当前启动任务配置进程基础身份权限初始化UID/GID权限组、SELinux安全上下文、ABI架构指令集、runtimeFlags虚拟机运行参数分配唯一 startSeq生成进程启动序列号用于异步流程的请求与结果精准匹配保存 pending 启动任务缓存未完成的进程启动请求防止异步调度丢失任务异步投递启动任务通过mProcStartHandler异步执行handleProcessStart()规避主线程阻塞发起进程创建请求最终调用Process.start()正式向Zygote发起进程创建调用。四、发起Zygote请求Socket通信传递启动参数4.1 统一入口Process.start()handleProcessStart()最终调用Process.start()该方法仅做请求转发不参与具体fork逻辑。源码路径frameworks/base/core/java/android/os/Process.javapublic static ProcessStartResult start(...) { // 转发请求至ZygoteProcess由Zygote完成进程创建 return ZYGOTE_PROCESS.start(...); }4.2 ZygoteProcess组装Socket请求参数源码路径frameworks/base/core/java/android/os/ZygoteProcess.javaZygoteProcess.start()调用startViaZygote()完整组装Zygote启动参数核心参数包括进程身份uid、gid、权限组运行配置runtimeFlags、targetSdkVersion、ABI指令集安全配置seInfo安全上下文进程信息进程名、App数据目录核心入口android.app.ActivityThread参数组装完成后通过Zygote Socket发送至Zygote常驻进程Socket通信协议极简 参数总数 换行分隔的所有参数 结束标识system_server发送请求后阻塞等待Zygote返回新进程PID完成进程创建握手。五、Zygote核心逻辑fork进程 进程专属化5.1 接收Socket请求解析启动参数源码路径frameworks/base/core/java/com/android/internal/os/ZygoteConnection.javaZygote服务端通过processCommand()监听Socket请求解析system_server传递的所有参数过滤非法请求后执行核心fork逻辑。5.2 fork进程创建Linux子进程Zygote调用forkAndSpecialize()通过JNI调用底层C方法nativeForkAndSpecialize()完成Linux进程fork。Zygote fork 的核心优势在于复用预加载环境。Zygote 在启动阶段会提前完成大量 Framework 类、资源和运行时环境的初始化。App 进程通过fork()创建后可以继承这些已经准备好的运行时状态借助 LinuxCopy-On-WriteCOW写时复制机制未修改的内存页可以在不同进程之间共享从而减少重复加载带来的启动时间和内存开销。5.3 进程专属化Specialize核心隔离阶段fork后的子进程默认是Zygote的「克隆体」必须通过专属化处理才能变成独立App进程底层SpecializeCommon()核心操作修改进程 UID/GID、权限组脱离 Zygote 身份根据目标进程配置设置 SELinux 安全上下文设置进程名称等进程级属性关闭或清理不应由子进程继承的文件描述符及资源。至此fork 出来的子进程完成从“Zygote 克隆体”到“独立 App 进程”的身份和资源隔离随后进入 App 进程初始化阶段。六、App进程初始化从Native层到Java层入口6.1 Zygote初始化运行环境源码路径frameworks/base/core/java/com/android/internal/os/ZygoteInit.java子进程专属化完成后回到Java层执行handleChildProc()调用ZygoteInit.zygoteInit()完成App进程基础环境初始化RuntimeInit.commonInit()初始化日志、异常捕获、时区等通用运行环境ZygoteInit.nativeZygoteInit()Native层初始化Binder线程池核心保障App与系统服务通信RuntimeInit.applicationInit()定位App进程Java主入口。6.2 反射启动ActivityThread主入口findStaticMain()通过反射找到ActivityThread.main()方法作为新进程的Java层唯一入口正式进入App应用层逻辑。6.3 ActivityThread.main()进入 App Java 层主线程源码路径frameworks/base/core/java/android/app/ActivityThread.javaActivityThread.main()是普通 App 进程进入 Java Framework 层后的核心入口。此时 App 进程虽然已经由 Zygote fork 创建完成但 Application 和 Activity 等组件尚未完成初始化后续还需要通过attach()与 system_server 建立联系。特殊系统进程、Instrumentation调试进程等不适用此入口核心逻辑初始化主线程Looper、消息队列搭建App主线程消息循环创建ActivityThread实例应用层核心调度类执行attach()向AMS完成进程报到。public static void main(String[] args) { Looper.prepareMainLooper(); ActivityThread thread new ActivityThread(); // 核心向AMS上报进程启动完成 thread.attach(false, startSeq); Looper.loop(); throw new RuntimeException(Main thread loop unexpectedly exited); }七、进程绑定与组件启动从报到到页面渲染7.1 App进程向AMS报到attachattach()中通过Binder调用AMS.attachApplication()传递两个核心信息ApplicationThreadApp进程的Binder通信句柄AMS后续通过该句柄调度App组件startSeq启动序列号用于AMS校验进程合法性。7.2 AMS绑定进程通知App初始化ApplicationAMS.attachApplicationLocked()首先将当前 App 进程与ProcessRecord正式绑定并完成进程状态管理、死亡监听等工作。随后AMS 通过 App 进程提供的ApplicationThreadBinder 接口调用bindApplication()通知 App 进程开始初始化应用运行环境。注意Application 并不是由 AMS 直接创建的。bindApplication()跨进程到达 App 进程后由ActivityThread.handleBindApplication()真正完成 Application 初始化包括准备LoadedApk、ClassLoader 等运行环境创建应用 Context创建 Application 对象调用Application.attach()最终执行Application.onCreate()。整个过程可以概括为AMS ↓ attachApplicationLocked() ↓ ApplicationThread.bindApplication() ↓ Binder App进程 ↓ ActivityThread.handleBindApplication() ↓ 创建Application ↓ Application.attach() ↓ Application.onCreate()7.3 ATMS唤醒待启动ActivityApp 进程完成attachApplication()后AMS/ATMS 根据当前进程状态继续推进之前等待的 Activity 启动任务。对于此前因进程不存在而暂存的启动请求ATMS 会继续执行 Activity 启动流程最终进入realStartActivityLocked()。最终通过ClientTransaction事务机制向App进程发送启动指令依次执行Activity实例创建 → attach绑定 → onCreate → onStart → onResume完成页面渲染展示。八、核心概念区分很多开发者容易混淆「进程启动」和「页面启动」这里做明确界定进程创建Zygote fork子进程、初始化虚拟机与运行环境仅完成「应用载体搭建」Application初始化App上下文、类加载器、资源加载完成应用环境就绪Activity启动页面实例创建、生命周期执行、UI渲染是用户真正看到的App启动。Zygote fork ↓ “舞台”搭建完成 ↓ ActivityThread.attach() ↓ App进程向系统“报到” ↓ bindApplication() ↓ Application初始化 ↓ realStartActivityLocked() ↓ Activity创建 ↓ onCreate / onStart / onResume ↓ “演员”正式登场总结进程只是舞台Activity才是演员舞台就绪不代表演员登场。所以Android 的“App 启动”并不是一个单一动作而是“进程创建 → Application 初始化 → Activity 启动”的连续过程。九、完整核心源码链路图ATMS.startProcessAsync() 异步发起进程创建请求避免持有ATMS锁时同步调用AMS ↓ ActivityManagerInternal.startProcess() 跨模块调用进入AMS进程管理逻辑 ↓ AMS.startProcess() AMS接收进程启动请求 ↓ ProcessList.startProcessLocked() 准备进程启动参数UID/GID、SELinux、ABI、runtimeFlags、startSeq等 ↓ handleProcessStart() 异步执行真正的进程创建操作 ↓ Process.start() 统一进程启动入口转交ZygoteProcess ↓ ZygoteProcess.startViaZygote() 组装Zygote启动参数准备Socket请求 ↓ Zygote Socket system_server向Zygote发送进程创建请求 ↓ ZygoteConnection.processOneCommand() Zygote解析请求参数准备fork ↓ Zygote.forkAndSpecialize() fork创建子进程并完成UID/GID、SELinux等进程专属化 ↓ ZygoteInit.zygoteInit() 初始化App运行环境Runtime、Binder等 ↓ ActivityThread.main() 进入App Java层主线程创建Looper并实例化ActivityThread ↓ ActivityThread.attach() App进程向system_server“报到” ↓ AMS.attachApplicationLocked() 绑定ProcessRecord与App进程完成进程管理状态初始化 ↓ ApplicationThread.bindApplication() AMS通知App进程开始初始化Application ↓ ActivityThread.handleBindApplication() App进程真正初始化Application、Context、ClassLoader等运行环境 ↓ Application.onCreate() Application初始化完成 ↓ ATMS.attachApplication() ATMS继续处理此前等待的Activity启动任务 ↓ realStartActivityLocked() 创建Activity启动事务准备启动Activity ↓ ClientTransaction 通过事务机制向App进程发送Activity启动指令 ↓ ActivityThread App主线程执行Activity启动事务 ↓ Activity.onCreate() → onStart() → onResume() Activity完成生命周期启动页面最终展示十、全文总结Android App冷启动的进程诞生流程是一套系统分层、异步解耦、安全隔离的精密机制1.调度层ATMS负责页面调度异步触发进程创建规避锁死问题2.准备层AMSProcessList完成进程权限、架构、安全、运行参数的全套配置3.创建层Zygote依托COW机制高效fork进程通过专属化实现进程独立隔离4.初始化层App进程完成虚拟机、Binder、上下文初始化向系统报到绑定5.渲染层系统唤醒待启动Activity完成页面生命周期与UI展示。整套流程完美诠释了Android Framework「分工协作、异步解耦、安全可控」的核心设计思想也是App冷启动优化、进程保活、系统性能调优的核心理论基础。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价