从用户在 Launcher 桌面点击 App 图标,到 App 进程创建、Activity 启动、界面渲染并最终显示到屏幕上的完整源码级解析
基于 Android 16 (Baklava, API 36) / AOSP frameworks/base 源码 · 涵盖 13 个关键阶段
目录 — 完整流程 13 个阶段
全链路时序图 — 四进程交互
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.javapackages/apps/Launcher3/src/com/android/launcher3/Launcher.javapackages/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() == null) return; 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(), user, intent.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.startActivitySafely(Launcher.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, 0, null, 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),并不经过 AMS(AMS.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() 是启动流程的控制中心。它经过以下阶段:
execute() — 入口,初始化环境 resolveActivity() — 通过 PMS 解析 Intent,找到目标 Activity 的 ActivityInfo executeRequest() — 详细校验:权限、Intent 组件、语音会话等 startActivityUnchecked() — 不持锁的核心调度逻辑 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 流程详解:
system_server 调用 Process.start()→ZygoteProcess.start()→startViaZygote()打开 Socket — 连接到 /dev/socket/zygote写入参数 — UID、GID、包名、目标类名 android.app.ActivityThread等Zygote 收到请求 — ZygoteServer.runSelectLoop()从 Socket 读取ZygoteConnection.processCommand()— 解析参数Zygote.forkAndSpecialize()— native fork 系统调用子进程 → handleChildProc()→ZygoteInit.zygoteInit()→RuntimeInit.applicationInit()最终执行 — 通过反射调用 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(0, 0, 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 提交给 BufferQueue。SurfaceFlinger(独立的系统进程)从 BufferQueue 中取出各层 Buffer,进行硬件合成(通过 HWC / GPU),最终将合成结果送显到屏幕。
App 进程 │ draw() 写入 Graphic Buffer │ │ queueBuffer() (生产者入队) └--> BufferQueue │ │ dequeueBuffer() (消费者取出) └--> SurfaceFlinger │ │ 收集所有 Layer 的 Buffer │ (App + StatusBar + NavBar + ...) │ │ HWC / GPU 合成 │ └--> Display (屏幕) │ │ Vsync 信号读取 Frame Buffer │ └── 屏幕显示画面从 draw 到屏幕显示的完整管线:
App 进程 draw → View 树递归 draw → 内容写入 Surface 的 Graphic Buffer BufferQueue 生产者-消费者模型 → App 是 BufferProducer,将 filled buffer 入队 → SurfaceFlinger 是 BufferConsumer,dequeue buffer 进行合成 SurfaceFlinger 合成 → 收集所有 Layer(App窗口、StatusBar、NavigationBar 等)的 Buffer → 通过 Hardware Composer (HWC) 或 GPU 进行硬件合成 → 合成结果写入 Display 的 Frame Buffer 显示到屏幕 → 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.javapackages/apps/Launcher3/src/com/android/launcher3/Launcher.javapackages/apps/Launcher3/src/com/android/launcher3/views/ActivityContext.java
Activity 框架层
frameworks/base/core/java/android/app/Activity.javaframeworks/base/core/java/android/app/Instrumentation.javaframeworks/base/core/java/android/app/ActivityThread.javaframeworks/base/core/java/android/app/ActivityManager.java
AMS / ATMS 服务层
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.javaframeworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.javaframeworks/base/services/core/java/com/android/server/wm/ActivityStarter.javaframeworks/base/services/core/java/com/android/server/wm/ActivityStartController.javaframeworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
ClientTransaction 调度层
frameworks/base/core/java/android/app/servertransaction/ClientTransaction.javaframeworks/base/core/java/android/app/servertransaction/TransactionExecutor.javaframeworks/base/core/java/android/app/servertransaction/LaunchActivityItem.javaframeworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
Zygote 进程层
frameworks/base/core/java/com/android/internal/os/ZygoteInit.javaframeworks/base/core/java/com/android/internal/os/ZygoteConnection.javaframeworks/base/core/java/com/android/internal/os/Zygote.javaframeworks/base/core/java/android/os/ZygoteProcess.java
Window / View 层
frameworks/base/core/java/com/android/internal/policy/PhoneWindow.javaframeworks/base/core/java/com/android/internal/policy/DecorView.javaframeworks/base/core/java/android/view/ViewRootImpl.javaframeworks/base/core/java/android/view/WindowManagerGlobal.java
渲染 / 显示层
frameworks/base/core/java/android/view/Choreographer.javaframeworks/base/core/java/android/view/Surface.javaframeworks/base/graphics/java/android/graphics/HardwareRenderer.javaframeworks/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 的 mContentParent,View 树还在内存里,没上屏。真正上屏要等 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 看 ActivityStart、bindApplication、inflate各段耗时。
Q18.(追问)启动白屏 / 黑屏哪来的?
冷启动 fork 进程 + Application + 首帧绘制需要时间,这段窗口系统显示 windowBackground 主题作为占位——白色就白屏、黑色就黑屏。解法:给启动 Activity 配单独的 windowBackground 主题(放 logo),让占位变成品牌闪屏,视觉上"秒开"。
Android Framework 源码深度分析 — App 启动全流程 Based on Android 16 (Baklava, API 36) — AOSP frameworks/base
夜雨聆风