乐于分享
好东西不私藏

Android App 启动流程源码深度分析

Android App 启动流程源码深度分析

从用户在 Launcher 桌面点击 App 图标,到 App 进程创建、Activity 启动、界面渲染并最终显示到屏幕上的完整源码级解析

基于 Android 16 (Baklava, API 36) / AOSP frameworks/base 源码 · 涵盖 13 个关键阶段


目录 — 完整流程 13 个阶段

序号
阶段
说明
01
Launcher 点击图标
用户点击桌面图标 → startActivity
02
Instrumentation → ATMS
Binder IPC 跨进程调用
03
ATMS → ActivityStarter
解析 Intent、权限检查、创建 ActivityRecord
04
ActivityStarter.executeRequest
详细校验、Intent Flag 处理、构建 ActivityRecord
05
ZygoteProcess → Zygote Fork
Socket 通信 fork 新进程
06
ActivityThread.main()
新进程入口、Looper、attach 到 AMS
07
Application 创建绑定
handleBindApplication → Application.onCreate()
08
ClientTransaction 机制
ATMS → ClientTransaction → TransactionExecutor
09
Activity 实例化
newActivity → attach → onCreate
10
PhoneWindow & DecorView
setContentView → installDecor → View 树构建
11
Resume & WMS 添加窗口
handleResumeActivity → ViewRootImpl → WMS
12
Choreographer & performTraversals
Vsync 信号 → measure → layout → draw
13
Surface & SurfaceFlinger
绘制到 Surface → SurfaceFlinger 合成显示

全链路时序图 — 四进程交互

 Launcher 进程  | (1) onClick  | (2) startActivity(intent)  | (3) Instrumentation.execStartActivity  |  |---- Binder IPC (IActivityTaskManager) ----> system_server 进程  |                        | (4) ATMS.startActivity(直达,不经 AMS)  |                        | (5) ATMS.startActivityAsUser  |                        | (6) ActivityStartController.obtainStarter  |                        | (7) ActivityStarter.execute  |                        | (8) executeRequest (校验+权限+创建Record)  |                        | (9) startActivityUnchecked  |                        | (10) startActivityInner (Task调度)  |                        |  |                        | (11) startSpecificActivity 判断进程是否存在  |                        | Process.start()  |                        |  |                        |---- Socket ----> Zygote 进程  |                        |                    | ZygoteServer.runSelectLoop  |                        |                    | ZygoteConnection.processCommand  |                        |                    | Zygote.forkAndSpecialize  |                        |                    |  |                        |                    |---- fork() ----> App 进程 (新创建)  |                        |                    |                   |  |                        |                    |                   | (12) ZygoteInit  |                        |                    |                   | (13) ActivityThread.main()  |                        |                    |                   |     Looper.prepareMainLooper()  |                        |                    |                   |     thread.attach(false)  |                        |                    |                   |  |                        |<--- Binder ---- attachApplication <----|  |                        |                    |                   |  |                        |---- Binder ---- bindApplication ------>|  |                        |                    |                   | (14) handleBindApplication  |                        |                    |                   |     makeApplicationInner  |                        |                    |                   |     Application.onCreate()  |                        |                    |                   |  |                        | (15) 构建 ClientTransaction  |                        |   + LaunchActivityItem  |                        |   + ResumeActivityItem  |                        |                    |                   |  |                        |---- Binder ---- scheduleTransaction -->|  |                        |                    |                   |  |                        |                    |                   | (16) TransactionExecutor.execute  |                        |                    |                   |     LaunchActivityItem.execute  |                        |                    |                   |     -> handleLaunchActivity  |                        |                    |                   |     -> performLaunchActivity  |                        |                    |                   |       -> Instrumentation.newActivity (反射)  |                        |                    |                   |       -> activity.attach -> new PhoneWindow  |                        |                    |                   |       -> callActivityOnCreate -> onCreate  |                        |                    |                   |         -> setContentView -> installDecor  |                        |                    |                   |           -> generateDecor -> DecorView  |                        |                    |                   |           -> inflate(layoutResID) -> View树  |                        |                    |                   |  |                        |                    |                   |   ResumeActivityItem.execute  |                        |                    |                   |   -> handleResumeActivity  |                        |                    |                   |     -> performResumeActivity -> onResume  |                        |                    |                   |     -> wm.addView(DecorView)  |                        |                    |                   |       -> new ViewRootImpl  |                        |                    |                   |       -> ViewRootImpl.setView  |                        |                    |                   |         -> requestLayout  |                        |                    |                   |         -> addToDisplayAsUser -> WMS  |                        |                    |                   |  |                        |                    |                   | (17) scheduleTraversals  |                        |                    |                   |     Choreographer.postCallback  |                        |                    |                   |     Vsync 信号到来  |                        |                    |                   |  |                        |                    |                   | (18) performTraversals  |                        |                    |                   |     relayoutWindow (获取Surface)  |                        |                    |                   |     performMeasure (测量View树)  |                        |                    |                   |     performLayout  (布局View树)  |                        |                    |                   |     performDraw    (绘制到Surface)  |                        |                    |                   |  |                        |                    |                   | (19) SurfaceFlinger 合成  |                        |                    |                   |  |                        |                    |                   \-- OK 界面显示到屏幕

01 | Launcher 点击图标 → startActivity

源码位置:

  • packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java
  • packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
  • packages/apps/Launcher3/src/com/android/launcher3/views/ActivityContext.java

Launcher 本身就是一个运行在独立进程的普通 App。它通过 LauncherModel 维护桌面快捷方式、文件夹、Widget 的数据模型。每个图标被点击时,Launcher 给该 View 打上一个 ItemInfo tag(记录图标对应的 Intent、包名等信息),统一的点击监听器据此分发。

真实调用链

View.setOnClickListener(ItemClickHandler.INSTANCE)   // BubbleTextView 等图标 View 注册的监听      │  (OnClickListener INSTANCE = ItemClickHandler::onClick)      ▼ItemClickHandler.onClick(View v)                     // 解析 v.getTag() 的 ItemInfo 类型      ├─ WorkspaceItemInfo → onClickAppShortcut()      ├─ AppInfo           → startAppShortcutOrInfoActivity()  // 直接启动      ├─ FolderInfo        → onClickFolderIcon()               // 打开文件夹,不启动 App      └─ ...            ▼ItemClickHandler.startAppShortcutOrInfoActivity(v, item, launcher)      ▼Launcher.startActivitySafely(v, intent, item)        // Launcher 重写:处理 resume 延迟      └─ super.startActivitySafely(...)            ▼ActivityContext.startActivitySafely(v, intent, item) // interface 的 default 方法,真正干活      │  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)      ▼context.startActivity(intent, optsBundle)            → 进入第 02 阶段(frameworks/base)
// packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.javapublicclassItemClickHandler{// 所有桌面图标 View 共用的点击监听器(方法引用)publicstaticfinal OnClickListener INSTANCE = ItemClickHandler::onClick;// 1. 用户点击图标,统一入口:按 View 的 tag(ItemInfo)类型分发privatestaticvoidonClick(View v){if (v.getWindowToken() == nullreturn;        Launcher launcher = Launcher.getLauncher(v.getContext());if (!launcher.getWorkspace().isFinishedSwitchingState()) return;        Object tag = v.getTag();if (tag instanceof WorkspaceItemInfo) {            onClickAppShortcut(v, (WorkspaceItemInfo) tag, launcher);          // 桌面快捷方式        } elseif (tag instanceof FolderInfo) {            onClickFolderIcon(v);                                              // 文件夹        } elseif (tag instanceof AppInfo) {            startAppShortcutOrInfoActivity(v, (AppInfo) tag, launcher);        // 抽屉里的 App        }// ... LauncherAppWidgetInfo / AppPairInfo / ItemClickProxy 等其它分支    }// 2. 桌面快捷方式:检查禁用/安装中状态后,转交给启动逻辑publicstaticvoidonClickAppShortcut(View v, WorkspaceItemInfo shortcut, Launcher launcher){if (shortcut.isDisabled() && handleDisabledItemClicked(shortcut, launcher)) {return;        }// ... promise icon / 安装中应用的特殊处理 ...        startAppShortcutOrInfoActivity(v, shortcut, launcher);    }// 3. 取出图标对应的 Intent,最终调 Launcher.startActivitySafelyprivatestaticvoidstartAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher){        Intent intent = item.getIntent();                      // 图标建模时就存好的启动 Intentif (intent == null) {thrownew IllegalArgumentException("Input must have a valid intent");        }// ... FLAG_START_FOR_RESULT 的特殊情况会用 startActivityForResult ...        launcher.startActivitySafely(v, intent, item);         // ← 关键:进入 Launcher 的启动流程    }}
// packages/apps/Launcher3/src/com/android/launcher3/views/ActivityContext.java// ActivityContext 是个 interface,startActivitySafely 是其 default 方法(真正干活的地方)。// Launcher(以及它的父类 StatefulActivity)实现/继承了这个 interface。default RunnableList startActivitySafely(View v, Intent intent, @Nullable ItemInfo item){    Context context = (Context) this;// 安全模式 / 深度快捷方式 等校验 ...// 构造启动动画选项(图标放大→展开到新窗口的动画)    ActivityOptionsWrapper options = v != null ? getActivityLaunchOptions(v, item)            : makeDefaultActivityOptions(-1);    UserHandle user = item == null ? null : item.user;    Bundle optsBundle = options.toBundle();// 关键:在 Intent 上加 NEW_TASK 标志//   —— 因为 App 必须在它自己的 Task 里运行,而不是复用 Launcher 的 Task    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);if (v != null) {        intent.setSourceBounds(Utilities.getViewBounds(v));    // 记录图标位置,用于启动动画    }try {if (user == null || user.equals(Process.myUserHandle())) {            context.startActivity(intent, optsBundle);         // ← 同用户:标准 startActivity        } else {// 工作资料/克隆用户:走 LauncherApps.startMainActivity            context.getSystemService(LauncherApps.class)                    .startMainActivity(intent.getComponent(), userintent.getSourceBounds(), optsBundle);        }// ... 上报启动埋点 ...return options.onEndCallback;    } catch (NullPointerException | ActivityNotFoundException | SecurityException e) {        Toast.makeText(context, R.string.activity_not_found, Toast.LENGTH_SHORT).show();    }returnnull;}

context.startActivity(intent, optsBundle) 之后,控制权就离开 Launcher 进程,进入 frameworks/base —— 即第 02 阶段的 Activity.startActivity → Instrumentation.execStartActivity。Launcher 自身定义的 Launcher.startActivitySafelyLauncher.java)主要做一件事:如果 Launcher 当前不处于 resumed 状态,就把启动推迟到下一次 resume(避免与手势动画冲突),真正逻辑仍在父级 ActivityContext.startActivitySafely

注意: Launcher 调用 startActivity 时会携带 FLAG_ACTIVITY_NEW_TASK,因为 App 需要在自己的 Task 中运行,而不是在 Launcher 的 Task 中。


02 | Instrumentation.execStartActivity → Binder IPC → ATMS

源码位置:

frameworks/base/core/java/android/app/Instrumentation.javaframeworks/base/core/java/android/app/ActivityTaskManager.java

// frameworks/base/core/java/android/app/Instrumentation.javapublic ActivityResult execStartActivity(        Context who, IBinder contextThread, IBinder token,        Activity target, Intent intent, int requestCode, Bundle options){    IApplicationThread whoThread = (IApplicationThread) contextThread;// ... ActivityMonitor 拦截逻辑(测试/监控用)...try {// 跨进程前的准备:迁移 ClipData、标记 Intent 即将离开本进程        intent.migrateExtraStreamToClipData(who);        intent.prepareToLeaveProcess(who);// 注意(Android 10 之后):Instrumentation 直接调用 ATMS,不再经过 AMS。//   ActivityTaskManager.getService() 返回 IActivityTaskManager 的 Binder 代理,//   这次 Binder 调用直达 system_server 中的 ActivityTaskManagerService。//   参数 whoThread = ApplicationThread(App 进程的 Binder 端,system_server 通过它回调)//   参数 token = Launcher Activity 的 Binder tokenint result = ActivityTaskManager.getService().startActivity(            whoThread,                    // IApplicationThread — App 端 Binder 回调接口            who.getOpPackageName(),       // callingPackage = "com.android.launcher3"            who.getAttributionTag(),      // attribution tag            intent,                       // 包含目标 Activity 的 ComponentName            intent.resolveTypeIfNeeded(who.getContentResolver()), // MIME type            token,                        // Launcher Activity 的 mToken            target != null ? target.mEmbeddedID : null,            requestCode, 0null, options);// 检查启动结果(如权限拒绝、Activity 不存在等错误会在这里抛出异常)        notifyStartActivityResult(result, options);        checkStartActivityResult(result, intent);    } catch (RemoteException e) {thrownew RuntimeException("Failure from system", e);    }returnnull;}

Instrumentation 是 Android 的"仪表盘"类,负责监控 Activity 的所有生命周期调用。它是 App 进程与 system_server 进程之间的桥梁。

关键步骤:通过 ActivityTaskManager.getService() 获取 IActivityTaskManager 的 Binder 代理对象,然后跨进程直达 system_server 中的 ATMS 的 startActivity 方法(不再经过 AMS)。

// frameworks/base/core/java/android/app/ActivityTaskManager.java// 获取 ATMS 的 Binder 代理(Singleton 懒加载)publicstatic IActivityTaskManager getService(){return IActivityTaskManagerSingleton.get();}privatestaticfinal Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =new Singleton<IActivityTaskManager>() {@Overrideprotected IActivityTaskManager create(){// 通过 ServiceManager 获取名为 "activity_task" 的 Binder 服务final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);return IActivityTaskManager.Stub.asInterface(b);    }};

Binder 通信关键对象:

  • IActivityTaskManager — ATMS 的 Binder 接口,App 通过它的 Proxy 调用 ATMS
  • IApplicationThread — App 进程的 Binder 接口(内部类 ApplicationThread),ATMS/AMS 通过它回调 App
  • token (IBinder) — Launcher Activity 的唯一标识,ATMS 用它关联 ActivityRecord

历史说明: Android 10 之前,App 通过 ActivityManager.getService()(IActivityManager)调用 AMS.startActivity,再由 AMS 转发给 ATMS。Android 10 之后 Instrumentation 改为直接调用 ATMS,AMS.startActivity(见阶段 03)虽然保留并仍委托 ATMS,但已不是 App 启动的主路径。


03 | ATMS → ActivityStartController → ActivityStarter(AMS 兼容转发见下)

源码位置:frameworks/base/services/core/java/com/android/server/am/ActivityManagerServiceframeworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService

// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService// AMS — 只做转发,真正逻辑在 ATMSpublicintstartActivity(IApplicationThread caller, String callingPackage,        Intent intent, ...){// 直接委托给 ActivityTaskManagerServicereturn mActivityTaskManager.startActivity(        caller, callingPackage, null/*callingFeatureId*/, intent,        resolvedType, resultTo, resultWho, requestCode,        startFlags, profilerInfo, bOptions);}

请求通过 Binder 跨进程到达 system_server,进入 ATMS (ActivityTaskManagerService)。注意:App 端的 Instrumentation 直接调用的是 IActivityTaskManager.startActivity(直达 ATMS),并不经过 AMSAMS.startActivity 仍保留并转发 ATMS,但已不是 App 启动主路径,见阶段 02 的历史说明)。

调用链:

ATMS.startActivity() → ATMS.startActivityAsUser() → ActivityStartController.obtainStarter() → ActivityStarter.execute()

Android 10 之后,Activity 相关的任务调度从 AMS 拆分到了 ATMS,ATMS 负责所有 Activity 栈管理、启动调度等核心逻辑。下面的 AMS.startActivity 代码(转发 ATMS)作为兼容遗留保留参考。

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService// ATMS — 获取 ActivityStarter 并配置参数后执行privateintstartActivityAsUser(IApplicationThread caller, ...){// 检查并修正 userId    userId = getActivityStartController().checkTargetUser(userId, ...);// 通过 ActivityStartController 获取 ActivityStarter(对象池模式)//   然后设置各种参数,最终 execute()return getActivityStartController()        .obtainStarter(intent, "startActivityAsUser")        .setCaller(caller)                     // IApplicationThread        .setCallingPackage(callingPackage)      // "com.android.launcher3"        .setCallingFeatureId(callingFeatureId)        .setResolvedType(resolvedType)          // MIME type        .setResultTo(resultTo)                   // Launcher Activity 的 token        .setResultWho(resultWho)        .setRequestCode(requestCode)        .setStartFlags(startFlags)        .setProfilerInfo(profilerInfo)        .setActivityOptions(opts)        .setUserId(userId)        .execute();  // 核心:启动执行!}

04 | ActivityStarter.executeRequest — 详细校验与构建 ActivityRecord

源码位置:frameworks/base/services/core/java/com/android/server/wm/ActivityStarter

// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter// ActivityStarter.execute() — 入口方法intexecute(){// 1. 如果还没有解析 Activity,通过 PMS 解析 Intentif (mRequest.activityInfo == null) {        mRequest.resolveActivity(mSupervisor);// 内部调用 PackageManagerService.resolveIntent()// 获取 ResolveInfo → ActivityInfo(包含包名、类名、launchMode 等)    }synchronized (mService.mGlobalLock) {// 2. 记录启动日志和指标final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);        launchingState = mSupervisor.getActivityMetricsLogger()            .notifyActivityLaunching(mRequest.intent, caller, callingUid);// 3. 核心调用:executeRequest        res = executeRequest(mRequest);    }}

ActivityStarter.execute() 是启动流程的控制中心。它经过以下阶段:

  1. execute() — 入口,初始化环境
  2. resolveActivity() — 通过 PMS 解析 Intent,找到目标 Activity 的 ActivityInfo
  3. executeRequest() — 详细校验:权限、Intent 组件、语音会话等
  4. startActivityUnchecked() — 不持锁的核心调度逻辑
  5. startActivityInner() — 真正将 Activity 放入 Task/TaskFragment,并触发后续 resume 流程(进程决策在其下游的 startSpecificActivity,见下)
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter// executeRequest — 详细校验并构建 ActivityRecordprivateintexecuteRequest(Request request){// 1. 一系列错误检查    WindowProcessController callerApp = mService.getProcessController(caller);if (err == START_SUCCESS && intent.getComponent() == null) {        err = START_INTENT_NOT_RESOLVED;    }if (err == START_SUCCESS && aInfo == null) {        err = START_CLASS_NOT_FOUND;    }// 2. 权限检查    abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, ...);// 3. 构造 ActivityRecord(system_server 中代表 Activity 的数据结构)final ActivityRecord r = new ActivityRecord.Builder(mService)        .setCaller(callerApp)        .setIntent(intent)        .setActivityInfo(aInfo)        .setConfiguration(mService.getGlobalConfiguration())        .setResultTo(sourceRecord)        .build();// 4. 进入 startActivityUnchecked    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, ...);}// startActivityUnchecked → startActivityInnerprivateintstartActivityUnchecked(...){    mService.deferWindowLayout();  // 暂停 WMS 布局try {// 真正的核心:startActivityInner        result = startActivityInner(r, sourceRecord, ...);    } finally {        startedActivityRootTask = handleStartResult(r, options, result, ...);    }}

startActivityInner — Task 调度的核心(ActivityStarter.java)

startActivityInner 真正完成"把 Activity 安放进 Task"的工作,但它本身不判断进程、不创建进程——它的出口是触发 resume。精简源码:

// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.javaintstartActivityInner(final ActivityRecord r, ActivityRecord sourceRecord, ...){// 1. 初始化状态、计算 launchFlags(含 NEW_TASK 等)    setInitialState(r, options, ...);    computeLaunchingTaskFlags();    mIntent.setFlags(mLaunchFlags);// 2. 查找可复用 Task,没有则新建 —— launchMode / Intent flags 在此落地final Task reusedTask = resolveReusableTask(...);final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();finalboolean newTask = targetTask == null;          // 是否要新建 Task// 3. 合法性校验(是否允许在此 task / 新 task 上启动)int startResult = isAllowedToStart(r, newTask, targetTask);if (startResult != START_SUCCESS) return startResult;// 4. 把 ActivityRecord 放进 Taskif (targetTaskTop != null) {        recycleTask(targetTask, targetTaskTop, ...);      // 复用已有 Task(singleTop/singleTask 命中复用)    } else {        mAddingToTask = true;    }if (newTask) {        setNewTask(taskToAffiliate);                       // 新建 Task    } elseif (mAddingToTask) {        addOrReparentStartingActivity(targetTask, ...);    // 加到现有 Task    }// 5. 移到前台、URI 授权、准备启动if (mDoResume && !avoidMoveToFront()) {        mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);    }    mTargetRootTask.startActivityLocked(mStartActivity, ...);// 6. 关键出口:触发 resume —— 注意这里不直接 fork 进程!if (mDoResume) {        mRootWindowContainer.resumeFocusedTasksTopActivities(                mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);    }return START_SUCCESS;}

职责:launchMode 决策 → 找/建 Task → ActivityRecord 入栈 → 移前台 → 触发 resume。

通往 Zygote 的衔接链(进程决策发生在下游,不在 startActivityInner 里):

startActivityInner  └─ mRootWindowContainer.resumeFocusedTasksTopActivities(...)       └─ targetRootTask.resumeTopActivityUncheckedLocked(...)            └─ ActivityTaskSupervisor.startSpecificActivity(...)   ← 真正的进程决策点

startSpecificActivity(ActivityTaskSupervisor.java)按"目标进程是否存在"分叉,这正是冷启动 / 热启动、以及是否进入阶段 05(Zygote fork)的分界(省略了 try-catch 与 sandbox 分支):

// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.javavoidstartSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig){// 目标进程是否已在运行?final WindowProcessController wpc =            mService.getProcessController(r.processName, r.info.applicationInfo.uid);if (wpc != null && wpc.hasThread()) {// —— 热启动:进程已存在 → 直接调度生命周期(走 ClientTransaction,见阶段 08)        realStartActivityLocked(r, wpc, andResume, checkConfig);return;    }// —— 冷启动:进程不存在 → 去 forkfinalboolean isTop = andResume && r.isTopRunningActivity();    mService.startProcessAsync(r, knownToBeDead, isTop,            isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY                  : HostingRecord.HOSTING_TYPE_ACTIVITY);}
  • 进程已存在 → realStartActivityLocked() → 构建 ClientTransaction 调度到 App(阶段 08)
  • 进程不存在 → mService.startProcessAsync() → Process.start() → ZygoteProcess.startViaZygote() → 进入阶段 05(Zygote fork 新进程)

05 | ZygoteProcess → Socket → Zygote Fork 新进程

源码位置:

frameworks/base/core/java/android/os/ZygoteProcessframeworks/base/core/java/com/android/internal/os/ZygoteInit

// frameworks/base/core/java/android/os/ZygoteProcess// system_server 端 — 构造 fork 参数并通过 Socket 发送给 Zygoteprivate Process.ProcessStartResult startViaZygote(...){    ArrayList<String> argsForZygote = new ArrayList<>();// 构造 fork 参数列表    argsForZygote.add("--runtime-args");    argsForZygote.add("--setuid=" + uid);           // App 的 Linux UID    argsForZygote.add("--setgid=" + gid);           // App 的 Linux GID    argsForZygote.add("--target-sdk-version=" + targetSdkVersion);    argsForZygote.add("--nice-name=" + niceName);   // 进程名,如 "com.example.app"    argsForZygote.add("--seinfo=" + seInfo);         // SELinux 信息    argsForZygote.add("--package-name=" + packageName);// 最关键的参数:新进程要运行的 Java 类    argsForZygote.add(processClass);// processClass = "android.app.ActivityThread"synchronized (mLock) {// 打开与 Zygote 的 Socket 连接        ZygoteState state = openZygoteSocketIfNeeded(abi);// 通过 Socket 将参数发送给 Zygote 进程,等待返回 fork 结果return zygoteSendArgsAndGetResult(state, zygotePolicyFlags, argsForZygote);    }}

当 ActivityStarter 发现目标 App 进程不存在时,system_server 通过 ZygoteProcess 向 Zygote 进程发送 Socket 消息请求 fork。Zygote 在系统启动时就已经预加载了所有常用类和资源,fork 出的子进程天然共享这些资源,所以启动速度很快。

// frameworks/base/core/java/com/android/internal/os/ZygoteInit// Zygote 进程 — 主入口(系统启动时执行一次)publicstaticvoidmain(String[] argv){// 禁止线程创建(fork 前的安全措施)    ZygoteHooks.startZygoteNoThreadCreation();// 1. 预加载 — 这是 Android App 启动快的关键优化    preload(bootTimingsTraceLog);//   preloadClasses()   — 预加载 3000+ 个常用 Java 类//   preloadResources() — 预加载常用 Drawable/Color 资源//   preloadOpenGL()    — 预加载 OpenGL/EGL//   preloadSharedLibraries() — 预加载 JNI 库//   preloadDexCaches() — 预加载 DEX 缓存//   这些在 fork 后被子进程 Copy-on-Write 共享!// 2. 创建 Zygote Socket Server(先建 Socket,再 fork system_server)    zygoteServer = new ZygoteServer(isPrimaryZygote);// 3. fork 出 system_serverif (startSystemServer) {        Runnable r = forkSystemServer(abiList, socketName, zygoteServer);if (r != null) r.run();    }// 4. 进入无限循环,等待 fork 请求    caller = zygoteServer.runSelectLoop(abiList);//   → ZygoteConnection.processCommand()//     → Zygote.forkAndSpecialize()//     → 子进程:handleChildProc() → ZygoteInit.zygoteInit()//       → RuntimeInit.applicationInit() → 找到 ActivityThread.main() 并调用if (caller != null) caller.run();}

Zygote Fork 流程详解:

  1. system_server 调用 Process.start() → ZygoteProcess.start() → startViaZygote()
  2. 打开 Socket — 连接到 /dev/socket/zygote
  3. 写入参数 — UID、GID、包名、目标类名 android.app.ActivityThread 等
  4. Zygote 收到请求 — ZygoteServer.runSelectLoop() 从 Socket 读取
  5. ZygoteConnection.processCommand() — 解析参数
  6. Zygote.forkAndSpecialize() — native fork 系统调用
  7. 子进程 → handleChildProc() → ZygoteInit.zygoteInit() → RuntimeInit.applicationInit()
  8. 最终执行 — 通过反射调用 ActivityThread.main()

06 | ActivityThread.main() — 新 App 进程的入口

源码位置:frameworks/base/core/java/android/app/ActivityThread

// frameworks/base/core/java/android/app/ActivityThreadpublicstaticvoidmain(String[] args){    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");    AndroidOs.install();    CloseGuard.setEnabled(false);    Environment.initForCurrentUser();// 1. 创建主线程 Looper//   这是为什么主线程能使用 Handler 的根本原因//   内部会创建 MessageQueue,并绑定到当前线程    Looper.prepareMainLooper();// 从命令行参数解析 startSeqlong startSeq = 0;if (args != null) {for (int i = args.length - 1; i >= 0; --i) {if (args[i] != null && args[i].startsWith("seq=")) {                startSeq = Long.parseLong(args[i].substring(4));            }        }    }// 2. 创建 ActivityThread 并 attach 到 AMS    ActivityThread thread = new ActivityThread();    thread.attach(false/*非系统进程*/, startSeq);if (sMainThreadHandler == null) {        sMainThreadHandler = thread.getHandler();  // 即 mH (ActivityThread.H)    }// 3. 进入主线程消息循环//   Looper.loop() 从 MessageQueue 取消息并分发给 Handler//   后续所有生命周期回调、UI 操作、输入事件都在这个循环中处理//   这个方法永远不会返回(除非出错)    Looper.loop();thrownew RuntimeException("Main thread loop unexpectedly exited");}// attach — 将 ApplicationThread 注册到 AMSprivatevoidattach(boolean system, long startSeq){    sCurrentActivityThread = this;    mSystemThread = system;if (!system) {        RuntimeInit.setApplicationObject(mAppThread.asBinder());// 获取 AMS 的 Binder 代理        IActivityManager mgr = ActivityManager.getService();try {// 将 mAppThread(ApplicationThread 的 Binder 对象)注册到 AMS//   mAppThread 是 ActivityThread 的内部类,实现了 IApplicationThread//   AMS 通过这个 Binder 回调 App 进程来发送各种指令            mgr.attachApplication(mAppThread, startSeq);        } catch (RemoteException ex) {throw ex.rethrowFromSystemServer();        }    }}

Zygote fork 出的子进程最终执行 ActivityThread.main(),这是每个 Android App 进程的 Java 层入口。它做了三件最关键的事。


07 | Application 创建与绑定

源码位置:frameworks/base/core/java/android/app/ActivityThread

// frameworks/base/core/java/android/app/ActivityThread// 绑定 ApplicationprivatevoidhandleBindApplication(AppBindData data){// 注册 UI 线程为敏感线程    VMRuntime.registerSensitiveThread();// 保存绑定数据    mBoundApplication = data;    mConfigurationController.setConfiguration(data.config);// 创建 Application 并调用 onCreate//   调用链://     data.info (LoadedApk).makeApplicationInner(false, mInstrumentation)//       → Instrumentation.newApplication()//         → (Application) cl.loadClass(appClass).newInstance()  // 反射创建//       → Application.attach(context)//       → Instrumentation.callApplicationOnCreate()//         → Application.onCreate()  你熟悉的入口!}

AMS 收到 attachApplication 后,会收集 App 的所有配置信息,通过 Binder 回调 App 进程的 ApplicationThread.bindApplication()。App 进程收到后在 handleBindApplication 中处理。

Application 创建的详细调用链:

 AMS (system_server)  │ attachApplication (Binder)  └--> ApplicationThread (App 进程)         │ sendMessage(BIND_APPLICATION)         └--> ActivityThread.H (主线程 Handler)                │ handleBindApplication                └--> ActivityThread                       │ LoadedApk.makeApplicationInner                       └--> Instrumentation                              │ newApplication() — 反射创建 Application 实例                              │ Application.attach(baseContext)                              │ callApplicationOnCreate()                              └--> Application                                     │ onCreate()  你熟悉的入口                                     └──

08 | ClientTransaction 机制 — system_server 调度到 App

源码位置:frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java

frameworks/base/core/java/android/app/servertransaction/TransactionExecutor

frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem

// frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java// ClientTransaction — AMS 发送给 App 的"任务包"// 包含两部分://   1. TransactionItems (回调列表) — 如 LaunchActivityItem、ResumeActivityItem//   2. ActivityLifecycleItem (最终状态) — 如 ResumeActivityItem 也作为最终状态// system_server 端构建 ClientTransaction 的代码(在 ATMS 的 RootWindowContainer 中)://   ClientTransaction clientTransaction = ClientTransaction.obtain(proc.thread, token);//   clientTransaction.addTransactionItem(LaunchActivityItem.obtain(...));  // 启动//   clientTransaction.setLifecycleStateRequest(ResumeActivityItem.obtain(...)); // 最终状态//   mService.getLifecycleManager().scheduleTransaction(clientTransaction);// 通过 Binder 发送到 App 进程://   → ApplicationThread.scheduleTransaction(clientTransaction)//   → ActivityThread.scheduleTransaction(transaction)//   → TransactionExecutor.execute(transaction)

Android 9 (Pie) 引入了 ClientTransaction 机制来替代以前的直接 Handler 消息。AMS 不再直接发 H.LAUNCH_ACTIVITY 等 message,而是构建一个 ClientTransaction 对象,里面包含一系列 ClientTransactionItem,每个 Item 代表一个操作(如启动 Activity、Resume Activity 等)。

App 进程收到后,由 TransactionExecutor 按顺序执行每个 Item。

// frameworks/base/core/java/android/app/servertransaction/TransactionExecutor// TransactionExecutor — 按顺序执行 ClientTransaction 中的每个 Itempublicvoidexecute(ClientTransaction transaction){    executeTransactionItems(transaction);}publicvoidexecuteTransactionItems(ClientTransaction transaction){final List<ClientTransactionItem> items = transaction.getTransactionItems();finalint size = items.size();for (int i = 0; i < size; i++) {final ClientTransactionItem item = items.get(i);if (item.isActivityLifecycleItem()) {            executeLifecycleItem(transaction, (ActivityLifecycleItem) item);        } else {            executeNonLifecycleItem(transaction, item, ...);        }    }}privatevoidexecuteNonLifecycleItem(...){// 如果 Item 需要某个前置生命周期状态,先将 Activity cycle 到那个状态if (item.shouldHaveDefinedPreExecutionState()) {finalint closestPreState = mHelper.getClosestPreExecutionState(r, ...);if (closestPreState != UNDEFINED) {            cycleToPath(r, closestPreState, transaction);        }    }// 执行 Item    item.execute(mTransactionHandler, mPendingActions);    item.postExecute(mTransactionHandler, mPendingActions);}
// frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem// LaunchActivityItem — 执行 Activity 启动publicvoidexecute(ClientTransactionHandler client,        PendingTransactionActions pendingActions){    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");// 构建 ActivityClientRecord — 封装了 Activity 启动所需的全部信息final ActivityClientRecord r = new ActivityClientRecord(        mActivityToken, mIntent, mIdent, mInfo, mOverrideConfig,        mReferrer, mVoiceInteractor, mState, mPersistentState,        mPendingResults, mPendingNewIntents, ...);// 调用 ActivityThread.handleLaunchActivity    client.handleLaunchActivity(r, pendingActions, mDeviceId, null);}
// frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem// ResumeActivityItem — 执行 Activity Resumepublicvoidexecute(ClientTransactionHandler client,        ActivityClientRecord r, PendingTransactionActions pendingActions){// 调用 ActivityThread.handleResumeActivity    client.handleResumeActivity(r, true/*finalStateRequest*/,        mIsForward, mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");}

09 | Activity 实例化与生命周期开始

源码位置:

frameworks/base/core/java/android/app/ActivityThreadframeworks/base/core/java/android/app/Instrumentation

frameworks/base/core/java/android/app/Activity

// frameworks/base/core/java/android/app/ActivityThread// handleLaunchActivitypublic Activity handleLaunchActivity(ActivityClientRecord r,        PendingTransactionActions pendingActions, ...){    unscheduleGcIdler();    mSomeActivitiesChanged = true;// 初始化硬件渲染器if (ThreadedRenderer.sRendererEnabled && ...) {        HardwareRenderer.preload();    }// 初始化 WindowManagerGlobal    WindowManagerGlobal.initialize();    GraphicsEnvironment.hintActivityLaunch();// 核心:执行 Activity 的完整启动final Activity a = performLaunchActivity(r, customIntent);if (a != null) {        r.createdConfig = new Configuration(...);        reportSizeConfigurations(r);    }return a;}
// frameworks/base/core/java/android/app/ActivityThread// performLaunchActivity — 最核心的方法private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){    ActivityInfo aInfo = r.activityInfo;// Step 1: 获取 LoadedApk(APK 包信息封装)if (r.packageInfo == null) {        r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo,            Context.CONTEXT_INCLUDE_CODE);    }// Step 2: 解析 ComponentName    ComponentName component = r.intent.getComponent();// component = ComponentName{com.example.app/com.example.app.MainActivity}// Step 3: 创建 Activity 的 Base Context    ContextImpl activityBaseContext = createBaseContextForActivity(r);    Activity activity = null;try {        java.lang.ClassLoader cl = activityBaseContext.getClassLoader();// Step 4: 通过 Instrumentation 反射创建 Activity 实例        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);    } catch (Exception e) { ... }try {// Step 5: 创建或获取 Application 实例        Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);if (activity != null) {// Step 7: 调用 activity.attach()//   创建 PhoneWindow、设置 Callback 等            activity.attach(activityBaseContext, this, mInstrumentation,                app, r.intent, r.activityInfo, r.token, ...);// Step 8: 调用 Activity.onCreate()if (r.isPersistable()) {                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);            } else {                mInstrumentation.callActivityOnCreate(activity, r.state);            }            r.setState(ON_CREATE);        }    }return activity;}
// frameworks/base/core/java/android/app/Instrumentation// 通过反射创建 Activitypublic Activity newActivity(ClassLoader cl, String className, Intent intent){    String pkg = intent.getComponent() != null        ? intent.getComponent().getPackageName() : null;return getFactory(pkg).instantiateActivity(cl, className, intent);// 默认实现:cl.loadClass(className).newInstance()}// 调用 Activity 的 onCreatepublicvoidcallActivityOnCreate(Activity activity, Bundle icicle){    prePerformCreate(activity);// activity.performCreate → Activity.onCreate()    activity.performCreate(icicle);    postPerformCreate(activity);}
// frameworks/base/core/java/android/app/Activity// Activity.performCreate → 调用我们熟悉的 onCreatefinalvoidperformCreate(Bundle icicle){    dispatchActivityPreCreated(icicle);    mCanEnterPictureInPicture = true;finalint windowingMode = getResources().getConfiguration()        .windowConfiguration.getWindowingMode();    mIsInMultiWindowMode = inMultiWindowMode(windowingMode);// 调用 Activity.onCreate(icicle) — 开发者重写的方法if (persistentState != null) {        onCreate(icicle, persistentState);    } else {        onCreate(icicle);    }    dispatchActivityPostCreated(icicle);}

Activity 生命周期 — 冷启动流程:

 Activity.attach() — 创建 PhoneWindow     ↓ Activity.onCreate() — setContentView()     ↓ Activity.onStart()     ↓ Activity.onResume() — 窗口即将可见     ↓ performTraversals — 界面显示到屏幕

10 | Activity.attach → PhoneWindow & DecorView 创建

源码位置:

frameworks/base/core/java/android/app/Activityframeworks/base/core/java/com/android/internal/policy/PhoneWindow

// frameworks/base/core/java/android/app/Activity// Activity.attach — 初始化 Activity 的所有核心成员finalvoidattach(Context context, ActivityThread aThread,        Instrumentation instr, ...){    mIntent = intent;    attachBaseContext(context);    mFragments.attachHost(null);    mActivityInfo = info;// 创建 PhoneWindow — 每个 Activity 有且仅有一个 Window    mWindow = new PhoneWindow(this, window, activityConfigCallback);    mWindow.setWindowControllerCallback(mWindowControllerCallback);    mWindow.setCallback(this);  // Activity 自身作为 Window 回调(处理触摸、按键等)    mWindow.setOnWindowDismissedCallback(this);    mWindow.getLayoutInflater().setPrivateFactory(this);if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {        mWindow.setSoftInputMode(info.softInputMode);    }    mUiThread = Thread.currentThread();  // 记录 UI 线程    mMainThread = aThread;              // ActivityThread 引用    mInstrumentation = instr;           // Instrumentation 引用    mToken = token;                     // AMS 分配的 Binder token    mApplication = application;         // Application 引用    mWindow.setWindowManager(..., mToken, mComponent.flattenToShortString());// 设置 WindowManager — 后续通过它将 DecorView 添加到 WMS    mWindowManager = mWindow.getWindowManager();}
// frameworks/base/core/java/android/app/Activity// setContentView — 在 Activity.onCreate() 中被开发者调用publicvoidsetContentView(int layoutResID){    getWindow().setContentView(layoutResID);  // 委托给 PhoneWindow    initWindowDecorActionBar();}
// frameworks/base/core/java/com/android/internal/policy/PhoneWindow// PhoneWindow.setContentViewpublicvoidsetContentView(int layoutResID){// 如果 DecorView 还没有创建,先安装if (mContentParent == null) {        installDecor();    } elseif (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {        mContentParent.removeAllViews();    }// 将布局资源 inflate 到 mContentParent (id = android:id/content)if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID, ...);        transitionTo(newScene);    } else {        mLayoutInflater.inflate(layoutResID, mContentParent);    }    mContentParent.requestApplyInsets();}// installDecor — 创建 DecorView 和内容区域privatevoidinstallDecor(){if (mDecor == null) {// 创建 DecorView — 窗口的最顶层 View        mDecor = generateDecor(-1);    }if (mContentParent == null) {// 根据 Theme/Feature 创建 DecorView 的内部布局结构        mContentParent = generateLayout(mDecor);// generateLayout 会根据 Window 的 Feature(如有没有 Title、ActionBar)// 选择不同的布局文件(如 screen_simple.xml、screen_title.xml 等)// 布局中包含一个 id="@android:id/content" 的 FrameLayout// 这就是 mContentParent — 开发者的布局会被添加到这里    }}

DecorView 内部结构:

 DecorView (FrameLayout)  ├── StatusBar 背景  ├── NavigationBar 背景  ├── TitleBar / ActionBar (取决于 Theme)  └── FrameLayout (id=android:id/content)       └── 开发者的布局 (由 setContentView inflate)

此时 View 树已经在内存中构建好了,但还没有显示。DecorView 只是在 App 进程内创建了,还没有被添加到 WindowManagerService。这一步要等到 handleResumeActivity 时才会发生。


11 | handleResumeActivity → Window 添加到 WMS

源码位置:

frameworks/base/core/java/android/app/ActivityThread

frameworks/base/core/java/android/view/ViewRootImpl

// frameworks/base/core/java/android/app/ActivityThread// handleResumeActivity — 界面变为可见的关键!publicvoidhandleResumeActivity(ActivityClientRecord r, ...){// 1. 调用 Activity.onResume()if (!performResumeActivity(r, finalStateRequest, reason)) {return;    }// performResumeActivity 内部://   → Activity.performResume()//     → mInstrumentation.callActivityOnResume(this)//       → Activity.onResume()final Activity a = r.activity;boolean willBeVisible = !a.mStartedActivity;// 2. 如果 DecorView 还没添加到 WindowManager,现在添加if (r.window == null && !a.mFinished && willBeVisible) {        r.window = r.activity.getWindow();   // PhoneWindow        View decor = r.window.getDecorView();  // DecorView        decor.setVisibility(View.INVISIBLE);   // 先设为不可见        ViewManager wm = a.getWindowManager();        WindowManager.LayoutParams l = r.window.getAttributes();        a.mDecor = decor;        l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;if (a.mVisibleFromClient) {            a.mWindowAdded = true;// 将 DecorView 添加到 WindowManager!//   → WindowManagerImpl.addView()//     → WindowManagerGlobal.addView()            wm.addView(decor, l);        }    }// 3. 如果已经添加了窗口,设为可见if (!r.activity.mFinished && willBeVisible) {        r.activity.makeVisible();// 内部:mDecor.setVisibility(View.VISIBLE)    }}
// frameworks/base/core/java/android/view/ViewRootImpl// ViewRootImpl.setView — 连接 View 树与 WMS 的关键方法publicvoidsetView(View view, WindowManager.LayoutParams attrs, ...){synchronized (this) {if (mView == null) {            mView = view;  // 保存 DecorView 引用// 1. 请求第一次布局绘制            requestLayout();// → checkThread() 检查是否在主线程// → scheduleTraversals()            InputChannel inputChannel = null;if (...) {                inputChannel = new InputChannel();            }// 2. 通过 Binder 将窗口注册到 WMStry {                res = mWindowSession.addToDisplayAsUser(                    mWindow,            // IWindow — App 端 Binder 回调                    mWindowAttributes,  // 窗口参数                    getHostVisibility(),                    mDisplay.getDisplayId(),                    userId,                    mInsetsController.getRequestedVisibleTypes(),                    inputChannel,       // 输出:输入通道                    mTempInsets, mTempControls,                    attachedFrame, compatScale);            } catch (RemoteException e) { ... }        }    }}
// frameworks/base/core/java/android/view/ViewRootImpl// scheduleTraversals — 安排下一帧执行 performTraversalsvoidscheduleTraversals(){if (!mTraversalScheduled) {        mTraversalScheduled = true;// 插入同步屏障(SyncBarrier),优先处理异步消息        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();// 通过 Choreographer 在下一个 Vsync 信号到来时执行 mTraversalRunnable        mChoreographer.postCallback(            Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);// mTraversalRunnable.run() → doTraversal() → performTraversals()    }}

12 | Choreographer Vsync → performTraversals → measure / layout / draw

源码位置:

frameworks/base/core/java/android/view/Choreographer

frameworks/base/core/java/android/view/ViewRootImpl

// frameworks/base/core/java/android/view/Choreographer// Choreographer.doFrame — Vsync 信号到来时执行voiddoFrame(long frameTimeNanos, int frame,        DisplayEventReceiver.VsyncEventData vsyncEventData){// 计算 jitter(帧延迟)finallong jitterNanos = startNanos - frameTimeNanos;if (jitterNanos >= frameIntervalNanos) {finallong skippedFrames = jitterNanos / frameIntervalNanos;if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {// 这就是你在 Logcat 中看到的 "Skipped N frames" 警告!            Log.i(TAG, "Skipped " + skippedFrames + " frames!  "                + "The application may be doing too much work on its main thread.");        }    }// 按优先级依次执行各类回调://   CALLBACK_INPUT      — 输入事件处理//   CALLBACK_ANIMATION  — 动画更新//   CALLBACK_INSETS_ANIMATION — Inset 动画//   CALLBACK_TRAVERSAL  — View 树遍历(performTraversals)//   CALLBACK_COMMIT     — 提交帧    doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameIntervalNanos);}

Choreographer 是 Android 的帧调度器,它接收硬件的 Vsync(垂直同步) 信号,每秒约 60 次(60fps)或 120 次(120fps),在每次信号到来时执行已注册的回调。performTraversals 就是通过 Choreographer 调度的。

 Vsync 信号 --> Choreographer.doFrame --> TraversalRunnable --> doTraversal --> performTraversals
// frameworks/base/core/java/android/view/ViewRootImpl// performTraversals — View 系统最核心的方法privatevoidperformTraversals(){final View host = mView;if (host == null || !mAdded) return;    mIsInTraversal = true;    mWillDrawSoon = true;// Step 0: relayoutWindow — 通过 WMS 获取/更新 Surface//   这一步非常关键:它通过 Binder 调用 WMS 的 relayoutWindow//   WMS 创建 SurfaceControl,分配 Graphic Buffer//   App 获得 Surface 对象,后续 draw 就画到这个 Surface 上    relayoutResult = relayoutWindow(params, ...);// Step 1: performMeasure — 测量 View 树if (!mStopped || mReportNextDraw) {int childWidthMeasureSpec = getRootMeasureSpec(...);int childHeightMeasureSpec = getRootMeasureSpec(...);        performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);    }// Step 2: performLayout — 布局 View 树if (didLayout) {        performLayout(lp, desiredWindowWidth, desiredWindowHeight);    }// Step 3: performDraw — 绘制 View 树if (!cancelDraw) {        performDraw();    }    mIsInTraversal = false;}
// frameworks/base/core/java/android/view/ViewRootImpl// Measure — 递归测量整棵 View 树privatevoidperformMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec){    Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");try {// 从 DecorView 开始递归调用每个子 View 的 measure        mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);// View.measure → onMeasure// ViewGroup.onMeasure → 遍历子 View → child.measure// 每个子 View 根据父 View 的 MeasureSpec 和自身 LayoutParams// 计算出自己的 measuredWidth / measuredHeight    } finally { Trace.traceEnd(...); }}// Layout — 递归布局整棵 View 树privatevoidperformLayout(WindowManager.LayoutParams lp, ...){    mInLayout = true;final View host = mView;try {// 从 DecorView 开始,递归布局每个子 View        host.layout(00, host.getMeasuredWidth(), host.getMeasuredHeight());// View.layout → onLayout// ViewGroup.onLayout → 遍历子 View → child.layout(left, top, right, bottom)// 每个子 View 确定自己在父容器中的精确位置    } finally { Trace.traceEnd(...); }    mInLayout = false;}
// frameworks/base/core/java/android/view/ViewRootImpl// Draw — 将 View 树内容绘制到 Surfaceprivatebooleandraw(boolean fullRedrawNeeded, ...){    Surface surface = mSurface;if (!surface.isValid()) returnfalse;// 有两种绘制路径:// 路径 A: 硬件加速绘制(默认,Android 4.0+)//   → mAttachInfo.mThreadedRenderer.draw(view)//   → HardwareRenderer 创建 RenderNode 树//   → 通过 GPU 绘制命令将 RenderNode 渲染到 Surface 的 Buffer 上//   → 性能远优于软件绘制// 路径 B: 软件绘制(兜底)//   → drawSoftware(surface, ...)//   → surface.lockCanvas() 获取 Canvas//   → mView.draw(canvas) 递归绘制整棵 View 树//     View.draw(Canvas) 做了://       1. drawBackground — 绘制背景//       2. onDraw — 绘制自身内容//       3. dispatchDraw — 绘制子 View//       4. drawForeground — 绘制前景/滚动条//   → surface.unlockCanvasAndPost(canvas)//   → 将 Buffer 提交给 SurfaceFlingerif (mAttachInfo.mThreadedRenderer != null && ...) {        mAttachInfo.mThreadedRenderer.draw(mView, ...);    } else {if (!drawSoftware(surface, ...)) returnfalse;    }}

13 | Surface → SurfaceFlinger 合成 → 屏幕显示

draw 完成后,App 进程将绘制好的 Buffer 通过 Surface.unlockCanvasAndPost() 或 HardwareRenderer 提交给 BufferQueueSurfaceFlinger(独立的系统进程)从 BufferQueue 中取出各层 Buffer,进行硬件合成(通过 HWC / GPU),最终将合成结果送显到屏幕。

 App 进程  │ draw() 写入 Graphic Buffer  │  │ queueBuffer() (生产者入队)  └--> BufferQueue         │         │ dequeueBuffer() (消费者取出)         └--> SurfaceFlinger                │                │ 收集所有 Layer 的 Buffer                │ (App + StatusBar + NavBar + ...)                │                │ HWC / GPU 合成                │                └--> Display (屏幕)                       │                       │ Vsync 信号读取 Frame Buffer                       │                       └── 屏幕显示画面

从 draw 到屏幕显示的完整管线:

  1. App 进程 draw → View 树递归 draw → 内容写入 Surface 的 Graphic Buffer
  2. BufferQueue 生产者-消费者模型 → App 是 BufferProducer,将 filled buffer 入队 → SurfaceFlinger 是 BufferConsumer,dequeue buffer 进行合成
  3. SurfaceFlinger 合成 → 收集所有 Layer(App窗口、StatusBar、NavigationBar 等)的 Buffer → 通过 Hardware Composer (HWC) 或 GPU 进行硬件合成 → 合成结果写入 Display 的 Frame Buffer
  4. 显示到屏幕 → Display 控制器在下一个 Vsync 信号时读取 Frame Buffer → 像素数据驱动屏幕显示

全链路调用总结

 用户点击桌面图标      |      v +------------------------------------------------------------------------------ |  Launcher 进程 |    Launcher.onClick → ItemClickHandler → startActivity(intent) |      → Activity.startActivityForResult |        → Instrumentation.execStartActivity |          → ActivityTaskManager.getService().startActivity() [Binder IPC] +----------------------------------+-------------------------------------------                                    | Binder IPC                                    v +------------------------------------------------------------------------------ |  system_server 进程 |    ATMS.startActivity → ATMS.startActivityAsUser |      → ActivityStartController.obtainStarter |        → ActivityStarter.execute |          → resolveActivity (通过 PMS 解析 Intent) |          → executeRequest (权限检查、构建 ActivityRecord) |          → startActivityUnchecked → startActivityInner (Task 调度) |          → startSpecificActivity(判断目标进程是否存在) |            +- 存在 → 构建 ClientTransaction 直接调度 |           +- 不存在 → Process.start → ZygoteProcess.startViaZygote [Socket] +----------------------------------+-------------------------------------------                                    | Socket (fork)                                    v +------------------------------------------------------------------------------ |  Zygote 进程 |    ZygoteServer.runSelectLoop → ZygoteConnection.processCommand |      → Zygote.forkAndSpecialize → 子进程 |        → handleChildProc → ZygoteInit.zygoteInit |          → RuntimeInit.applicationInit → 反射调用 ActivityThread.main() +----------------------------------+-------------------------------------------                                    |                                    v +------------------------------------------------------------------------------ |  App 进程(新创建) | |  ① ActivityThread.main() |     → Looper.prepareMainLooper() |     → thread.attach(false) → AMS.attachApplication(mAppThread) [Binder] |     → Looper.loop() | |  ② handleBindApplication |     → LoadedApk.makeApplicationInner → Application.onCreate() | |  ③ AMS 通过 ClientTransaction 调度 |     → ApplicationThread.scheduleTransaction [Binder 回调] |     → TransactionExecutor.execute |       → LaunchActivityItem.execute |         → handleLaunchActivity |           → performLaunchActivity |             → Instrumentation.newActivity (反射创建 Activity) |             → activity.attach → new PhoneWindow |             → Instrumentation.callActivityOnCreate |               → Activity.performCreate → Activity.onCreate() |                 → setContentView → PhoneWindow.setContentView |                   → installDecor → generateDecor(DecorView) |                   → mLayoutInflater.inflate(layoutResID, mContentParent) |       → ResumeActivityItem.execute |         → handleResumeActivity |           → performResumeActivity → Activity.onResume() |           → WindowManager.addView(DecorView) |             → WindowManagerGlobal.addView → new ViewRootImpl |             → ViewRootImpl.setView(DecorView) |               → requestLayout → scheduleTraversals |               → mWindowSession.addToDisplayAsUser [Binder→WMS] | |  ④ Choreographer 收到 Vsync → performTraversals |     → relayoutWindow (通过 WMS 获取 Surface) |     → performMeasure → View.measure (递归测量) |     → performLayout  → View.layout  (递归布局) |     → performDraw    → draw (绘制到 Surface) |       → Surface.unlockCanvasAndPost / HardwareRenderer |       → SurfaceFlinger 合成 → 屏幕显示 +------------------------------------------------------------------------------

关键源码文件索引

Launcher 层

  • packages/apps/Launcher3/src/com/android/launcher3/touch/ItemClickHandler.java
  • packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
  • packages/apps/Launcher3/src/com/android/launcher3/views/ActivityContext.java

Activity 框架层

  • frameworks/base/core/java/android/app/Activity.java
  • frameworks/base/core/java/android/app/Instrumentation.java
  • frameworks/base/core/java/android/app/ActivityThread.java
  • frameworks/base/core/java/android/app/ActivityManager.java

AMS / ATMS 服务层

  • frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
  • frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
  • frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
  • frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
  • frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

ClientTransaction 调度层

  • frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
  • frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
  • frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
  • frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java

Zygote 进程层

  • frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
  • frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
  • frameworks/base/core/java/com/android/internal/os/Zygote.java
  • frameworks/base/core/java/android/os/ZygoteProcess.java

Window / View 层

  • frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
  • frameworks/base/core/java/com/android/internal/policy/DecorView.java
  • frameworks/base/core/java/android/view/ViewRootImpl.java
  • frameworks/base/core/java/android/view/WindowManagerGlobal.java

渲染 / 显示层

  • frameworks/base/core/java/android/view/Choreographer.java
  • frameworks/base/core/java/android/view/Surface.java
  • frameworks/base/graphics/java/android/graphics/HardwareRenderer.java
  • frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

面试速查

以面试官视角整理的 18 道高频题,按 6 个梯度分组。

场景设定:面试官从具体场景切入——"用户在桌面点了一下 App 图标,到界面出来,中间发生了什么?先整体讲,我再挑细节追问。"

一、整体架构

Q1. 这个过程涉及哪几个进程?各自干什么?

四个进程协作:Launcher(发起,构造 Intent 调 startActivity)、system_server(大脑:权限校验、Task 调度、决定是否建进程、调度生命周期)、Zygote(孵化器,fork 出 App 进程)、App 进程(跑 ActivityThread.main,创建 Application、实例化 Activity、渲染上屏)。

Q2. 为什么这些步骤要跨进程?挤一个进程不行吗?

隔离与稳定。Launcher / system_server / App 各自独立进程,App 崩溃不能拖死系统,系统也不能信任任意 App 直接操作 Activity 栈。靠 Binder(普通调用)+ Socket(Zygote 通信)协作。

二、跨进程通信(Binder / Socket)

Q3. 第一次跨进程怎么发生?到达的是谁?

走 Instrumentation.execStartActivity → ActivityTaskManager.getService().startActivity(),拿到 IActivityTaskManager 的 Binder 代理,直达 ATMS

Q4.(陷阱)很多人说到达的是 AMS?

这是版本差异。Android 10 之前走 IActivityManager 到 AMS 再转发 ATMS;Android 10 之后 Instrumentation 直接调 ATMS。AMS.startActivity 现在只是转发壳,已不是 App 启动主路径。

Q5. 启动新进程也是 Binder 吗?为什么 Zygote 用 Socket?

不是 Binder,是 Socket。核心:fork() 要求单线程环境——fork 瞬间只能一个线程在跑,否则子进程会继承一个错乱的线程快照。Binder 依赖多线程线程池,fork 时其他 Binder 线程会被一并 fork 进去出问题。所以 Zygote 用单线程阻塞的 Socket,保证 fork 时干净。

三、system_server 内部调度

Q6. 请求进了 ATMS 之后怎么一步步走到启动?

ATMS.startActivity → startActivityAsUser → ActivityStartController.obtainStarter(对象池 + 链式 set)→ ActivityStarter.execute → executeRequest(校验 + 建 ActivityRecord)→ startActivityUnchecked → startActivityInner

Q7. executeRequest 和 startActivityInner 各负责什么?

  • executeRequest:校验(权限、Intent 合法性)+ 构造 ActivityRecord。
  • startActivityInner:Task 调度(launchMode、找/建 Task、ActivityRecord 入栈)。它本身不创建进程。

Q8.(重点)怎么判断冷启动还是热启动?在哪个方法?

在 ActivityTaskSupervisor.startSpecificActivity。先 getProcessController(processName, uid) 查进程:存在且活着 → realStartActivityLocked(热启动);不存在 → startProcessAsync(冷启动)。注意不是 startActivityInner,进程决策在它下游。

四、Zygote & 进程创建

Q9. 为什么用 Zygote fork 而不是 new 一个进程?

为了快。Zygote 启动时 preload 了 3000+ 类、资源、OpenGL、JNI 库,fork 出的子进程以 copy-on-write 共享,只有写时才复制。全新启动 JVM + 加载类会慢一个数量级。

Q10. fork 出的子进程入口在哪?怎么找到 ActivityThread.main?

经 handleChildProc → ZygoteInit.zygoteInit → RuntimeInit.applicationInit反射调用 android.app.ActivityThread.main。类名是 system_server 在 startViaZygote 时作为 processClass 通过 Socket 传给 Zygote 的。

五、生命周期与窗口

Q11. Application 什么时候创建?链路讲一下。

App 进程 attach 时,AMS.attachApplication 注册 ApplicationThread;system_server 回调 bindApplication,App 端 handleBindApplication → LoadedApk.makeApplicationInner → Instrumentation.newApplication(反射)→ Application.attach → onCreate()

Q12. Activity 怎么实例化?为什么用反射?

performLaunchActivity 里 Instrumentation.newActivity → AppComponentFactory.instantiateActivity → cl.loadClass(className).newInstance()。用反射是因为目标 Activity 类名运行时(Intent 里)才确定,Framework 编译期不知道,只能动态加载。

Q13. ClientTransaction 是什么?比老方案好在哪?

Android 9 引入。system_server 不再发零散的 H.LAUNCH_ACTIVITY 消息,而是构建 ClientTransaction(打包 LaunchActivityItem + ResumeActivityItem…)一次 Binder 发到 App,由 TransactionExecutor 按序执行。好处:生命周期可批处理、可组合、状态机化(能精确控制 cycle 到某个生命周期状态),比散落的 message 清晰、易维护。

Q14.(高频陷阱)setContentView 之后界面就显示了吗?

没有。setContentView 只是在 App 进程内把布局 inflate 到 DecorView 的 mContentParentView 树还在内存里,没上屏。真正上屏要等 handleResumeActivity:先 onResume,再把 DecorView 经 WindowManager.addView → ViewRootImpl.setView 注册到 WMS,之后由 Choreographer 触发 performTraversals 才显示。所以 onResume 时用户其实还看不到内容。

六、渲染与实战

Q15. performTraversals 怎么触发?和 Vsync 什么关系?

ViewRootImpl.setView → requestLayout → scheduleTraversals,往 Choreographer 注册 CALLBACK_TRAVERSAL。Choreographer 监听硬件 Vsync,下一个信号到来时 doFrame → doCallbacks → performTraversals。所以 measure/layout/draw 是按帧、跟屏幕刷新率对齐执行的,而不是立即执行。

Q16. 一帧里 performTraversals 依次做什么?

relayoutWindow(向 WMS 要 Surface / GraphicBuffer)→ performMeasure(递归测量)→ performLayout(递归定位)→ performDraw(默认硬件加速,ThreadedRenderer 用 GPU 渲染到 Surface 的 buffer)→ buffer 经 BufferQueue 交 SurfaceFlinger 合成上屏。

Q17.(实战)冷启动慢,有哪些优化方向?

顺着启动链路找瓶颈:

  • Application.onCreate——别做重初始化、别同步 IO,用懒加载/异步;
  • Activity.onCreate / setContentView——布局层别太深(影响 measure/layout),别主线程读大资源;
  • 首帧绘制——减少主线程阻塞,避免 performTraversals 跨帧(即 Logcat 里 "Skipped N frames" 的来源);
  • 系统侧——fork 进程不可避免,可用 SplashScreen / windowBackground 占位遮白屏。
  • 工具:Perfetto / systrace 看 ActivityStartbindApplicationinflate 各段耗时。

Q18.(追问)启动白屏 / 黑屏哪来的?

冷启动 fork 进程 + Application + 首帧绘制需要时间,这段窗口系统显示 windowBackground 主题作为占位——白色就白屏、黑色就黑屏。解法:给启动 Activity 配单独的 windowBackground 主题(放 logo),让占位变成品牌闪屏,视觉上"秒开"。


Android Framework 源码深度分析 — App 启动全流程 Based on Android 16 (Baklava, API 36) — AOSP frameworks/base