本文基于 Android 16(API Level 36)AOSP 源码,全文 8000+ 字,建议收藏。
从
startActivity()到Activity.onResume(),再到首帧显示,完整追踪一次 Activity 启动链路。
一、前言
Activity 启动流程是 Android Framework 中最经典、也最容易被追问的链路之一。
常见问题包括:
-
startActivity()到底经历了什么? -
Instrumentation为什么能 Hook Activity 启动? -
AMS和ATMS分别负责什么? -
ActivityThread是什么? -
Application.onCreate()和Activity.onCreate()谁先执行? -
LaunchMode在哪里生效? -
onResume()执行后界面是否已经显示? -
Android 16 对 Activity 启动有什么影响?
本文基于 Android 16(API Level 36)的 Framework 源码结构来分析。
先给结论:
Android 16 中,Activity 启动主链路并没有被重写。核心仍然是:应用进程通过
Instrumentation发起请求,System Server 中的ActivityTaskManagerService和ActivityStarter负责启动决策,目标进程中的ActivityThread负责创建 Activity 并执行生命周期。

整体链路如下:
Activity.startActivity()
↓
Instrumentation.execStartActivity()
↓ Binder
ActivityTaskManagerService
↓
ActivityStarter
↓
Task / RootWindowContainer
↓
ClientTransaction
↓ Binder
ActivityThread
↓
LaunchActivityItem
↓
performLaunchActivity()
↓
Activity.attach()
↓
Activity.onCreate()
↓
Activity.onStart()
↓
Activity.onResume()
↓
WindowManagerGlobal.addView()
↓
ViewRootImpl.setView()
↓ Binder
WindowManagerService.addWindow()
↓
ViewRootImpl.performTraversals()
↓
首帧显示
二、整体架构
一次 Activity 启动可以分成四个阶段:
阶段一:App 进程发起启动请求
阶段二:System Server 解析 Intent、校验权限、处理 Task 和启动模式
阶段三:目标 App 进程接收生命周期事务,创建 Activity
阶段四:执行 onCreate / onStart / onResume,并进入窗口显示流程
对应进程关系:
┌────────────────────┐
│ App Process │
│ startActivity() │
└─────────┬──────────┘
│ Binder
▼
┌────────────────────┐
│ System Server │
│ ATMS / ActivityStarter
└─────────┬──────────┘
│ Binder
▼
┌────────────────────┐
│ Target App Process │
│ ActivityThread │
└─────────┬──────────┘
▼
onCreate → onStart → onResume
▼
WindowManager / ViewRootImpl
▼
WMS / SurfaceFlinger
▼
首帧显示
重点:
App 进程负责发起请求,System Server 负责决策,目标 App 进程负责真正创建 Activity 和执行生命周期。
三、startActivity 与 Instrumentation
开发者通常这样启动页面:
java
Intent intent = new Intent(this, DetailActivity.class);
startActivity(intent);
进入 Activity 后,大致链路是:
java
Activity.startActivity()
↓
Activity.startActivityForResult()
↓
Instrumentation.execStartActivity()
Activity 自己并不会直接完成启动,它会把启动请求交给 Instrumentation。
Instrumentation 是应用进程内非常关键的代理类。它参与:
-
发起 Activity 启动:
execStartActivity() -
创建 Activity 实例:
newActivity() -
回调 Activity 生命周期:
callActivityOnCreate() -
回调 Application 生命周期:
callApplicationOnCreate()
🔍 源码印证:Instrumentation.execStartActivity()
java
// frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// ...
try {
intent.migrateExtraStreamToClipData(who);
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), who.getAttributionTag(),
intent, intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
// 关键:检查启动结果,失败会抛异常(ActivityNotFoundException 等)
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
在启动阶段,关键动作是:
Instrumentation.execStartActivity()
↓
ActivityTaskManager.getService().startActivity()
ActivityTaskManager.getService() 返回的是 System Server 中 ActivityTaskManagerService 的 Binder 代理。
所以从进程角度看:
App 进程
↓ Binder
System Server
重点:
Instrumentation.execStartActivity()是应用进程侧启动 Activity 的关键入口,所以插件化框架、自动化测试框架经常会从这里 Hook。checkStartActivityResult()会在启动失败时抛出明确的异常(如ActivityNotFoundException),这是开发者经常遇到的运行时异常来源。
四、ATMS 与 ActivityStarter
Android 10 之后,Activity 和 Task 管理从早期 ActivityManagerService 中拆分出来,主要由:
ActivityTaskManagerService
负责,简称 ATMS。
AMS 和 ATMS 大致分工是:
AMS:进程、Service、Broadcast、Provider 等管理
ATMS:Activity、Task、窗口层级、Activity 生命周期调度
但两者并不是完全割裂的。比如冷启动时,目标进程不存在,仍然需要 AMS / ProcessList 协助启动应用进程。
Activity 启动请求进入 ATMS 后,大致链路是:
ActivityTaskManagerService.startActivity()
↓
startActivityAsUser()
↓
ActivityStartController.obtainStarter()
↓
ActivityStarter.execute()
ActivityStarter 是 Activity 启动链路中最核心的决策类之一。AOSP 中对它的职责描述是:负责解释如何把一个 Intent 和启动 flags 转换成对应的 Activity、Task 和 Root Task。
它主要处理:
-
Intent 解析
-
Activity 是否存在
-
权限检查
-
exported 检查
-
后台启动限制检查
-
LaunchMode
-
Intent Flags
-
taskAffinity
-
是否复用已有 Task
-
是否复用已有 Activity
-
是否创建新的
ActivityRecord
核心链路大致是:
ActivityStarter.execute()
↓
executeRequest()
↓
startActivityUnchecked()
↓
startActivityInner()
🔍 源码印证:ActivityStarter 入口
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
try {
// 解析 Intent、权限校验等
res = executeRequest(request);
} finally {
onExecutionComplete();
}
return res;
}
private int executeRequest(Request request) {
// 1. 解析 Intent 到 ComponentName
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
// 2. 权限检查
int res = mService.getPermissionPolicy().checkStartActivity(...);
// 3. 创建 ActivityRecord
ActivityRecord r = new ActivityRecord.Builder(...).build();
// 4. 进入启动决策核心
return startActivityUnchecked(r, sourceRecord, ...);
}
重点:
ActivityStarter是 Activity 启动决策核心,决定"能不能启动、启动到哪个 Task、创建还是复用"。
五、LaunchMode、Flags 与 Task 决策
常见启动模式包括:
standard
singleTop
singleTask
singleInstance
singleInstancePerTask
这些启动模式不是在 Activity 自己内部生效,而是在 System Server 的启动决策阶段生效。
也就是说:
ActivityStarter / Task 相关逻辑
↓
决定创建新实例,还是复用已有实例
例如:
-
standard:通常创建新 Activity 实例。 -
singleTop:如果目标 Activity 已经位于栈顶,则复用并回调onNewIntent()。 -
singleTask:查找符合条件的已有 Task,可能复用已有 Activity,并清理其上的 Activity。 -
singleInstancePerTask:每个 Task 中只允许一个该 Activity 实例。
🔍 源码印证:startActivityUnchecked 中的启动模式判断
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
...) {
// 根据 launchMode 和 flags 设置启动标志
setInitialState(r, sourceRecord, ...);
// singleTop / FLAG_ACTIVITY_SINGLE_TOP 判断
if ((mLaunchMode == LAUNCH_SINGLE_TOP || mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP != 0)
&& r.isTopRunningActivity()) {
// 栈顶复用分支,最终会回调 onNewIntent()
return deliverToCurrentTopIfNeeded(r, sourceRecord);
}
// singleTask / singleInstance / FLAG_ACTIVITY_NEW_TASK 处理
if ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0
|| mLaunchMode == LAUNCH_SINGLE_TASK
|| mLaunchMode == LAUNCH_SINGLE_INSTANCE
|| mLaunchMode == LAUNCH_SINGLE_INSTANCE_PER_TASK) {
// 查找可复用的 Task 或 Activity
findOrCreateTask(r, sourceRecord);
}
// 继续执行启动流程
return startActivityInner(...);
}
startActivityUnchecked() 和后续 Task 逻辑会综合判断:
-
launchMode -
Intent Flags(FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_CLEAR_TOP、FLAG_ACTIVITY_SINGLE_TOP) -
taskAffinity -
调用方所在 Task
-
目标 Activity 是否已有实例
-
是否指定
ActivityOptions
最终决定:
创建新的 ActivityRecord
或复用已有 ActivityRecord
或创建新 Task
或复用已有 Task
或把已有 Task 移到前台
重点:
singleTask不是在Activity.onCreate()里生效的,而是在ActivityStarter.startActivityUnchecked()的源码分支中生效的。

六、Android 16:后台启动限制与 Intent 安全
Android 16 没有重写 Activity 启动主链路,但它在"是否允许启动"这个安全边界上有值得关注的变化。
1. 后台 Activity 启动限制
官方文档把后台 Activity 启动称为:
Background Activity Launch,简称 BAL
它指的是:
一个没有前台可见 Activity 的应用,或者通过其他应用传来的 PendingIntent,尝试启动新的 Activity。
后台 Activity 启动限制从 Android 10 就已经存在。Android 16 相关的重点是:SDK 36 新增了更推荐的 PendingIntent 授权模式:
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE
它的含义是:
只有发送 PendingIntent 的应用当前可见时,才允许把后台启动 Activity 的能力传递出去。
示例:
java
val options = ActivityOptions.makeBasic().apply {
pendingIntentBackgroundActivityStartMode =
ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE
}
pendingIntent.send(options.toBundle())
🔍 源码印证:后台启动检查入口
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int executeRequest(Request request) {
// ...
// 后台 Activity 启动限制检查
if (mService.mBackgroundActivityStartController != null) {
int balResult = mService.mBackgroundActivityStartController
.checkBackgroundActivityStart(callingUid, callingPid, callingPackage,
callingRealUid, callingRealPid, intent, resolvedType,
activityInfo, resultTo, options, mRequest.startResult);
if (balResult != ActivityManager.START_SUCCESS) {
return balResult;
}
}
// ...
}
这意味着分析 Android 16 上的 Activity 启动失败时,不能只看 Intent 和 Manifest,还要看:
-
调用方是否处于前台或满足 BAL 例外条件
-
是否通过 PendingIntent 启动
-
PendingIntent 创建方是否授权
-
PendingIntent 发送方是否授权
-
授权模式是否符合当前可见状态
2. StrictMode 诊断
Android 16 还提供了一个与后台 Activity 启动相关的调试能力:
java
StrictMode.setVmPolicy(
StrictMode.VmPolicy.Builder()
.detectBlockedBackgroundActivityLaunch()
.penaltyLog()
.build()
)
它可以帮助开发者发现:
-
当前被系统拦截的后台 Activity 启动
-
未来 targetSdk 升级后可能被拦截的启动行为
3. Intent Redirection 安全增强
Android 16 官方文档还提到,对 Intent Redirection 攻击提供默认安全增强。
Intent Redirection 指的是:攻击者控制一个嵌套 Intent,让受害 App 在自己的上下文中启动这个不可信 Intent,从而访问私有组件、触发敏感操作或获取 URI 权限。
典型风险代码类似:
Kotlin
val subIntent = intent.getParcelableExtra<Intent>("sub_intent")
startActivity(subIntent)
Android 16 提供默认防护,并提供新的 opt-out API:
java
subIntent.removeLaunchSecurityProtection()
但官方也强调,只有在明确知道风险并确认合法场景时才应该 opt-out。
🔍 源码印证:Intent Redirection 检查位置
虽然 AOSP 中该检查的具体实现位于 Intent 和 ActivityStarter 的权限校验阶段,但核心逻辑是在 System Server 解析嵌套 Intent 时,验证目标组件是否与原始 Intent 的授权范围匹配。大致位置如下:
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int resolveIntentAndActivity(...) {
// ...
// Android 16 新增:Intent Redirection 安全检查
if (!isIntentRedirectionAllowed(intent, callingUid)) {
return START_INTENT_REDIRECTION_NOT_ALLOWED;
}
// ...
}
重点:
Android 16 的这些变化影响的是 Activity 启动的合法性和安全边界,不是
startActivity()到ActivityThread的主链路重构。
七、realStartActivityLocked 与 ClientTransaction
当 ActivityStarter 完成启动决策后,会进入 Task 和窗口容器相关流程。
现代 Android 中,Activity 栈围绕下面这些对象组织:
RootWindowContainer
TaskDisplayArea
Task
TaskFragment
ActivityRecord
其中:
-
RootWindowContainer:窗口和任务层级的根容器。 -
TaskDisplayArea:Display 上承载 Task 的区域。 -
Task:任务栈。 -
TaskFragment:Task 内更细粒度的 Activity 容器。 -
ActivityRecord:System Server 中对 Activity 的服务端描述。
App 进程中的一个 Activity 实例,在 System Server 中对应一个 ActivityRecord。
典型链路是:
RootWindowContainer.resumeFocusedTasksTopActivities()
↓
Task.resumeTopActivityUncheckedLocked()
↓
TaskFragment.resumeTopActivity()
↓
realStartActivityLocked()
当系统决定真正启动目标 Activity 时,realStartActivityLocked() 会构造 ClientTransaction,然后通过 Binder 发送给目标应用进程。
可以理解为:
System Server 不直接执行 Activity.onCreate()
而是发送生命周期事务给 App 进程
由 App 主线程自己执行生命周期
🔍 源码印证:ClientTransaction 的构造与发送
java
// frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// ...
// 创建客户端事务
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.token);
// 添加 LaunchActivityItem(负责 onCreate)
clientTransaction.addCallback(LaunchActivityItem.obtain(
new Intent(r.intent), System.identityHashCode(r), r.info,
new Configuration(mService.getGlobalConfiguration()),
r.overrideConfig, r.compat, r.launchedFromPackage,
r.task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
r.isForward, proc.getProfilerInfo(), r.assistToken,
r.shareableActivityToken, r.getTargetSdkVersion(),
r.getProcessLimitInfo()));
// 设置最终生命周期状态为 RESUMED(包含 onStart 和 onResume)
if (andResume) {
clientTransaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(r.isForward,
r.shouldSendCompatFakeFocus()));
}
// 通过 Binder 发送给目标进程
clientTransaction.schedule();
// ...
}
典型事务包含:
LaunchActivityItem
ResumeActivityItem
早期 Android 使用 ActivityThread.H.LAUNCH_ACTIVITY 这类 Handler 消息调度 Activity 启动。Android P 之后,引入了更统一的 ClientTransaction,把客户端生命周期操作封装成事务。
一次 Activity 启动可以理解为:
ClientTransaction
├── callback: LaunchActivityItem
└── lifecycleStateRequest: ResumeActivityItem
其中:
-
LaunchActivityItem:负责创建 Activity,并执行onCreate()。 -
ResumeActivityItem:负责把 Activity 推进到 Resumed 状态。
需要注意:
onStart()不一定需要 System Server 单独下发一个StartActivityItem。当生命周期从 Created 推进到 Resumed 时,TransactionExecutor会根据生命周期路径执行中间状态,因此会触发onStart()。
八、冷启动:进程创建与 Application.onCreate
如果目标 Activity 所在进程还不存在,System Server 不能直接发送 LaunchActivityItem,必须先启动应用进程。
大致流程是:
ATMS / AMS
↓
ProcessList.startProcessLocked()
↓
ZygoteProcess.start()
↓
Zygote fork
↓
ActivityThread.main()
新进程启动后,会进入:
ActivityThread.main()
🔍 源码印证:ActivityThread.main()
java
// frameworks/base/core/java/android/app/ActivityThread.java
public static void main(String[] args) {
// 1. 创建主线程 Looper
Looper.prepareMainLooper();
// 2. 创建 ActivityThread 实例
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
// 3. 获取主线程 Handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
// 4. 启动 Looper 循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
这里会:
-
创建主线程 Looper
-
创建
ActivityThread -
调用
attach() -
通过 Binder 告诉系统进程:应用进程已经启动
随后进入应用绑定流程:
ActivityThread.main()
↓
ActivityThread.attach()
↓ Binder
ActivityManager.getService().attachApplication()
↓
ActivityManagerService.attachApplication()
↓
AMS / ATMS 协作完成应用绑定与 Activity 启动恢复
↓
ApplicationThread.bindApplication()
↓
ActivityThread.handleBindApplication()
↓
创建 Application
↓
Instrumentation.callApplicationOnCreate()
↓
Application.onCreate()
然后才是:
LaunchActivityItem
↓
ActivityThread.handleLaunchActivity()
↓
performLaunchActivity()
↓
Activity.onCreate()
所以结论是:
Application.onCreate()
↓
Activity.onCreate()
重点:
冷启动时,
Application.onCreate()先于Activity.onCreate()。Application.onCreate()主要发生在ActivityThread.handleBindApplication()阶段,而不是简单地说发生在performLaunchActivity()中。
九、ActivityThread 与 performLaunchActivity
目标 App 进程中,真正处理生命周期事务的是:
ActivityThread
链路大致是:
ApplicationThread.scheduleTransaction()
↓
ClientTransactionHandler.scheduleTransaction()
↓
ActivityThread.H 发送消息
↓
TransactionExecutor.execute()
↓
LaunchActivityItem.execute()
↓
ActivityThread.handleLaunchActivity()
↓
performLaunchActivity()
ActivityThread 虽然名字里有 Thread,但它不是普通意义上的线程类,而是 App 主线程的核心管理者。
performLaunchActivity() 是 Activity 实例真正创建的关键方法,主要做四件事。
🔍 源码印证:performLaunchActivity() 核心流程
java
// frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 1. 创建 Activity 的 Context(ContextImpl)
ContextImpl appContext = createBaseContextForActivity(r);
// 2. 反射创建 Activity 实例
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
} catch (Exception e) {
throw new RuntimeException("Unable to instantiate Activity", e);
}
// 3. 调用 Activity.attach(),绑定 Window、Application 等
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.activityConfigCallback,
r.assistToken, r.shareableActivityToken);
// 4. 回调 Activity.onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
return activity;
}
1. 创建 Activity 的 Context
系统会为 Activity 创建专属 ContextImpl:
createBaseContextForActivity()
这个 Context 会绑定:
-
LoadedApk
-
Resources
-
Display
-
Configuration
-
Activity token
2. 反射创建 Activity
Activity 实例通过 Instrumentation 创建:
Instrumentation.newActivity()
🔍 源码印证:Instrumentation.newActivity()
java
// frameworks/base/core/java/android/app/Instrumentation.java
public Activity newActivity(ClassLoader cl, String className, Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
// 反射加载并实例化 Activity
return (Activity) cl.loadClass(className).newInstance();
}
内部会使用 ClassLoader:
ClassLoader.loadClass()
↓
Constructor.newInstance()
所以 Activity 本质上是在应用进程内,通过 ClassLoader 反射创建的对象。
3. 调用 Activity.attach()
Activity 对象创建后,会调用:
activity.attach(...)
这里会绑定很多核心对象:
-
Context
-
Application
-
Instrumentation
-
Activity token
-
Window(创建 PhoneWindow)
-
WindowManager
-
FragmentController
其中非常关键的是 PhoneWindow,通常会在 Activity.attach() 阶段创建。
🔍 源码印证:Activity.attach() 中创建 PhoneWindow
java
// frameworks/base/core/java/android/app/Activity.java
final void attach(Context context, ...) {
attachBaseContext(context);
// 关键:创建 PhoneWindow
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
// ...
}
所以在 onCreate() 中调用:
getWindow()
是可用的。
4. 回调 Activity.onCreate()
最后通过:
Instrumentation.callActivityOnCreate()
↓
Activity.performCreate()
↓
Activity.onCreate()
执行开发者写的 onCreate()。
重点:
performLaunchActivity()创建 Activity 对象,完成 attach,然后通过Instrumentation回调onCreate()。
十、Window、onResume 与首帧显示
Activity.attach() 中会创建 PhoneWindow,但这不代表界面已经显示。
开发者在 onCreate() 中调用:
java
setContentView(R.layout.activity_main);
大致会进入:
Activity.setContentView()
↓
PhoneWindow.setContentView()
↓
PhoneWindow.installDecor()
↓
DecorView 创建 / 内容布局加载
结构大致是:
PhoneWindow
↓
DecorView
↓
ContentParent
↓
开发者布局 View
重点:
setContentView()只是把布局加载到DecorView中,不代表 View 已经完成 measure、layout、draw。
当 LaunchActivityItem 执行完后,TransactionExecutor 会继续根据目标生命周期状态推进。如果目标状态是 RESUMED,生命周期会从:
ON_CREATE
↓
ON_START
↓
ON_RESUME
依次推进。
大致调用是:
handleStartActivity()
↓
Activity.performStart()
↓
Activity.onStart()
然后:
handleResumeActivity()
↓
performResumeActivity()
↓
Activity.performResume()
↓
Activity.onResume()
🔍 源码印证:handleResumeActivity 与 onResume 后的窗口添加
java
// frameworks/base/core/java/android/app/ActivityThread.java
public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
boolean isForward, String reason) {
// 1. 执行 Activity.onResume()
if (!performResumeActivity(r, finalStateRequest, reason)) {
return;
}
// 2. 获取 DecorView
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
// 3. 将 DecorView 添加到 WindowManager(关键!)
if (r.activity.mVisibleFromClient) {
r.activity.mVisibleFromServer = true;
wm.addView(decor, l);
// 注意:此时只是 addView,View 的测量/布局/绘制尚未执行
}
}
更精确地说,onResume() 是在 handleResumeActivity() 中执行的。onResume() 返回后,ActivityThread 会继续在同一个主线程调度中,将 DecorView 通过本地调用交给 WindowManagerGlobal:
WindowManagerGlobal.addView()
随后应用进程内会创建 ViewRootImpl,并调用:
ViewRootImpl.setView()
ViewRootImpl.setView() 内部会通过 Binder 调用 WMS:
WindowManagerService.addWindow()
所以这段更准确的链路是:
handleResumeActivity()
↓
performResumeActivity()
↓
Activity.onResume()
↓
WindowManagerGlobal.addView()
↓
创建 ViewRootImpl
↓
ViewRootImpl.setView()
↓ Binder
WindowManagerService.addWindow()
🔍 源码印证:首帧绘制的真正入口 performTraversals()
java
// frameworks/base/core/java/android/view/ViewRootImpl.java
private void performTraversals() {
// 这个方法在 onResume 之后,由 Choreographer 的 VSYNC 信号触发
if (mLayoutRequested) {
// 执行 measure
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
}
if (mLayoutRequested) {
// 执行 layout
performLayout(lp, mWidth, mHeight);
}
// 执行 draw
performDraw();
}
注意:
performTraversals()不是 WMS 回调给 App 的方法,而是应用主线程在后续 VSYNC 驱动下执行的本地绘制流程。
完整首帧链路更接近:
onResume()
↓
WindowManagerGlobal.addView()
↓
ViewRootImpl.setView()
↓
WMS.addWindow()
↓
Choreographer 等待 VSYNC
↓
ViewRootImpl.performTraversals()
↓
measure
↓
layout
↓
draw
↓
RenderThread
↓
SurfaceFlinger 合成
↓
屏幕显示首帧
重点:
onResume()不是首帧完成的标志。从源码可以看到,onResume()执行完毕后立即 执行addView,但此时 View 的onMeasure/onLayout/onDraw尚未触发。首帧通常要等ViewRootImpl.performTraversals()执行,并经过渲染和合成后才真正显示到屏幕。

十一、完整时序图

十二、关键结论
1. startActivity 不是直接创建 Activity
startActivity() 最终会通过 Instrumentation.execStartActivity() 发起 Binder 调用,进入 System Server。从源码 Instrumentation.newActivity() 可以看出,Activity 实例不是在调用方直接创建的,而是在目标进程的 ActivityThread.performLaunchActivity() 中通过 ClassLoader 反射创建。
2. 启动决策发生在 System Server
ActivityStarter.startActivityUnchecked() 会综合判断:
Intent
权限
exported
LaunchMode
Intent Flags
taskAffinity
Task 状态
后台启动限制
然后决定是否允许启动,以及创建还是复用 Activity / Task。
3. 生命周期由 App 主线程执行
System Server 不直接调用:
Activity.onCreate()
Activity.onStart()
Activity.onResume()
从 realStartActivityLocked() 源码可以看到,它通过 ClientTransaction 把生命周期事务发送给目标 App 进程,由 ActivityThread 和 TransactionExecutor 在主线程执行。
4. Application.onCreate 先于 Activity.onCreate
冷启动时,ActivityThread.main() 会先执行 handleBindApplication() 触发 Application.onCreate(),之后才处理 LaunchActivityItem 执行 performLaunchActivity() 和 Activity.onCreate()。
所以不能简单地说 Application 是在 performLaunchActivity() 中才创建并执行 onCreate()。
5. onResume 不等于首帧显示
从 handleResumeActivity() 源码可以看到,onResume() 返回后,会执行 wm.addView(decor, l),将 DecorView 添加到 WindowManager。但真正首帧显示还要经过 ViewRootImpl.performTraversals() 中的 measure/layout/draw,以及 SurfaceFlinger 合成。
6. Android 16 的重点是安全边界增强
Android 16 没有重写 Activity 启动主链路。它更值得关注的是:
-
PendingIntent 后台启动 Activity 的显式授权(
MODE_BACKGROUND_ACTIVITY_START_ALLOW_IF_VISIBLE) -
StrictMode.detectBlockedBackgroundActivityLaunch() -
Intent Redirection 默认安全增强
这些影响的是"是否允许启动"和"如何诊断启动失败",不是生命周期主链路本身。
十三、不展开项与参考资料
以下内容虽然和 Activity 或窗口体验相关,但不属于本文启动主链路,因此不展开:
-
Predictive Back
Android 16 默认启用 Predictive Back 系统动画,并影响
onBackPressed()和KEYCODE_BACK,但它属于返回导航链路,不属于startActivity()创建链路。 -
Edge-to-edge 与大屏适配
Android 16 对 edge-to-edge、大屏方向、宽高比、resizability 有行为变化,但它们主要影响窗口展示和适配,不改变 Activity 启动主流程。
-
singleInstancePerTask是否在 Android 16 更严格源码中存在相关处理,但没有足够证据证明这是 Android 16 特有变化,因此本文不把它作为 Android 16 新变化展开。
-
厂商 ROM 差异
本文基于 AOSP 和官方文档,厂商 ROM 可能对窗口、任务、启动限制做定制。
参考资料:
-
Android 16 Behavior Changes
https://developer.android.com/about/versions/16/behavior-changes-16
-
Background Activity Launch Restrictions
https://developer.android.com/guide/components/activities/background-starts
-
Intent Redirection
https://developer.android.com/privacy-and-security/risks/intent-redirection
-
AOSP ActivityStarter.java
-
AOSP BackgroundActivityStartController.java
-
AOSP ActivityOptions.java
-
AOSP ActivityThread.java