Android Framework(二)——Activity启动流程

注意(WARNING):本文含有大量AOSP源码,阅读过程中如出现头晕、目眩、恶心、犯困等症状属正常情况,作者本人亦无法避免症状产生,故不承担任何法律责任。

本文所贴源码全部来自 Android API 29 Platform,即 Android 10.0。

Android 中待启动的 Activity 分为两类,一种是 App 的Root Activity,也就是根Activity,另一种是普通的 Activity。

两类 Activity 的启动过程有不少重叠的部分,根 Activity 特殊的点在于,启动它时涉及到整个应用进程的启动,因此更具有指导意义。

本文将通过分析根Activity的启动过程来理解Android 10中Activity的启动流程。根 Activity 的启动过程分为三个部分,分别是:

  • Launcher 请求 ATMS 过程
  • ATMS 调用 ApplicationThread 过程
  • ActivityThread启动Activity过程

另外还涉及到目标App进程的启动过程,不过本文主要讨论Activity的启动流程,App进程的启动将会在下篇文章讲解。

下面就以这三个部分为基础来分析根 Activity 的启动过程。

前置知识

为了避免阅读源码过程中出现不适,这里先简单介绍一些后面会出现的相关类。

相关类介绍

  • ActivityThread:整个 App main 方法所在的类,所谓主线程就是指它所执行的线程,所以通常会称其为主线程。它负责管理应用程序进程的主线程的执行,处理 ATMS 的调度和执行Activity,Broadcast及相关操作。
  • ApplicationThread:它是 ActivityThread 的一个内部类,继承自 IApplicationThread.Stub,是一个 IBinder。ActivityThread 通过它来进行 IPC 调用,与 SystemServer 通信。
  • Intrumentation:用于监控应用程序与系统交互,启动 Activity 或者调用 Activity、Application 的生命周期都需要经过它的处理。
  • ActivityTaskManager:Activity,Service 等与 ATMS 跨进程交互的接口,ATMS的辅助类。后文简称为 ATM。
  • ActivityTaskManagerService:管理 Activity 和它的回退栈、任务栈的系统服务,Android 10以前是 AMS 的工作,Android 10中将部分工作从 AMS 抽离为 ATMS。后文将简称为 ATMS。
  • ActivityRecord:system_server进程中用来描述Activity的数据类型。ActivityRecord中存储了Activity的信息,如所在的进程名称,应用的包名,所在的任务栈的taskAffinity等,与ActivityClientRecord、Activity的是一一对应关系。
  • ActivityClientRecord:App进程中用来描述Activity的数据类型。
  • TaskRecord:表示一个任务栈,记录了Activity启动的先后顺序,栈中严格按照先进后出的特性维护一系列ActivityRecord。
  • ActivityStack:负责维护TaskRecord,内部保存了当前Stack中所有的Task列表。
  • ActivityDisplay:管理所有ActivityStack,表示当前屏幕的抽象,内部维护了mHomeStack、mStacks、mPreferredToFocusableStack和mLastFocusedStack等ActivityStack。
  • RootActivityContainer:Android10中新增的类,由ActivityStackSupervisor中抽离而来,其作为Activity容器的根节点,负责管理所有的ActivityDisplay。
  • ActivityStackSupervisor:Android系统中Activity的最大管家,通过持有RootActivityContainer来间接管理所有的Activity。
  • ClientLifecycleManager:组合多个客户端生命周期转换和请求,作为单个事务来执行。

Activity栈管理机制

Activity栈结构如下图所示。

Activity栈管理模型

用关系链表来表示它们的关系:

1
2
3
4
5
6
ActivityStackSupervisor.mRootActivityContainer
-> RootActivityContainer.mActivityDisplays
-> ActivityDisplay.mStacks
-> ActivityStack.mTaskHistory
-> TaskRecord.mActivities
-> ActivityRecord

Launcher 请求 AMS 过程

当我们启动系统时首先启动的App就是 Launcher,通过 Launcher 我们可以点击图标启动任何一个App,继而启动它的 Main Activity。整个过程发生在Launcher#startActivitySafely方法中。

Launcher#startActivitySafely

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

1
2
3
4
5
6
7
8
@Override
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
@Nullable String sourceContainer) {
···
boolean success = super.startActivitySafely(v, intent, item, sourceContainer);
···
return success;
}

startActivitySafely 方法继承自 BaseDraggingActivity:

packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
@Nullable String sourceContainer) {
···
// 1
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (v != null) {
intent.setSourceBounds(getViewBounds(v));
}
try {
boolean isShortcut = (item instanceof WorkspaceItemInfo)
&& (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
|| item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
&& !((WorkspaceItemInfo) item).isPromise();
if (isShortcut) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item, sourceContainer);
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
// 2
startActivity(intent, optsBundle);
AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
Process.myUserHandle(), sourceContainer);
} else {
getSystemService(LauncherApps.class).startMainActivity(
intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(), user,
sourceContainer);
}
getUserEventDispatcher().logAppLaunch(v, intent, user);
if (item != null) {
InstanceId instanceId = new InstanceIdSequence().newInstanceId();
logAppLaunch(item, instanceId);
}
return true;
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
return false;
}

代码注释1处是我们比较熟悉的了,通过设置 FLAG_ACTIVITY_NEW_TASK flag让 Activity 在新的任务栈中启动。在注释 2 处会调用 startActivity 方法,这个 startActivity 方法在 Activity 中实现。

Activity#startActivity

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}

startActivity 方法最终会调用到 startActivityForResult 方法并传入-1表示不需要返回。

Activity#startActivityForResult

继续来看startActivityForResult:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
// Activity mParent
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}

cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}

mParent 属性会在 Activity attach 时设置,表示 Activity 启动时的父 Activity,但 Main Activity 的 mParent 是为 null 的,因此会进入 if 判断中。if 代码块中调用到了 Instrumentation#execStartActivity,剩下都交给 Instrumentation 来处理。

Instrumentation#execStartActivity

Instrumentation 类主要用来监控应用程序与系统交互,mMainThread 对象是 ActivityThread,通过 getApplicationThread 方法获取 ApplicationThread 对象。ApplicationThread 继承自 Stub,也就是 Binder,这为我们后面与 AMS 通信提供了基础。

1
private class ApplicationThread extends IApplicationThread.Stub

继续跟踪源码,来到 Instrumentation#execStartActivity 方法中:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
···
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}

这里使用 binder IPC 调用到了 ActivityTaskManagerService(ATMS)中。

ATMS 是个远程服务,需要通过 ServiceManager 来获取,ServiceManager 底层最终调用的还是 Native 层的 ServiceManager,它是 Binder 的守护服务,通过它能够获取在 Android 系统启动时注册的系统服务,这其中就包含这里提到的 ATMS。获取服务的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}

@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);// 1
return IActivityTaskManager.Stub.asInterface(b); // 2
}
};

注释 1 处通过 ServiceManager 获取对应的系统服务,也就是 IBinder 类型的 ATMS 引用。注释 2 处将它转换成 ActivityTaskManager 类型的对象,这段代码采用的是 AIDL,IActivityTaskManager.java 类是由 AIDL 工具在编译时自动生成的,IActivityTaskManager.aidl 的文件路径为 frameworks/base/core/java/android/app/IActivityTaskManager.aidl。 要实现进程间通信,服务端也就是 ATMS 只需要继承 IActivityTaskManager.Stub 类并实现相应的方法也就可以了。

小结

我们回顾一下 Launcher 所做工作,startActivity 最终都会调用到 startActivityForResult,而启动一个 Activity 必须通过系统服务来执行,因此会使用 Launcher 的 ApplicationThread 来发起一次 IPC 调用,最终在 Instrumentation#execStartActivitiesAsUser 中请求 ATMS 来启动 Activity。

这个过程的时序图如下所示。

Launcher请求ATMS过程时序图

ATMS 到 ApplicationThread 的调用过程

Launcher 请求 AMS 后 ,代码逻辑已经进入 ATMS 中,接着是 ATMS 到 ApplicationThread 的调用流程。

ActivityTaskManagerService#startActivity

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

1
2
3
4
5
6
7
8
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}

ATMS中会调用startActivityAsUser方法,这里需要注意一点就是startActivityAsUser方法比startActivity多了一个参数,为UserHandle.getCallingUserId(),ATMS根据这个参数来判断调用者的权限。

ActivityTaskManagerService#startActivityAsUser

frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
// 1
enforceNotIsolatedCaller("startActivityAsUser");

// 2
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

// 3
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();
}

注释1处判断调用者进程是否被隔离,如果被隔离则抛出SecurityException异常。

注释2处检查调用者是否有权限,如果没有权限也会抛出SecurityException异常。

注释3出通过ActivityStartController来获取一个ActivityStarter,并且配置了一些参数,这里要注意setMayWait方法传入了userId,会将ActivityStarter的mayWait属性置为true,后面会用到。

ActivityStarter是Android 7.0中新加入的类,它是加载Activity的控制类,会收集所有的逻辑来决定如何将 Intent和Flags转换为Activity,并将 Activity和Task以及Stack相关联。

ActivityStarter#execute

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int execute() {
try {
if (mRequest.mayWait) {
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
} else {
···
}
} finally {
onExecutionComplete();
}
}

由于mRequest.mayWait被置为true,因此会调用startActivityMayWait方法。startActivityMayWait多了几个参数,需要注意的是TaskRecord代表启动Activity所在的栈。

ActivityStarter#startActivityMayWait

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
// intent中不允许携带文件描述符
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
···
// 解析Intent
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
0 /* matchFlags */,
computeResolveFilterUid(
callingUid, realCallingUid, mRequest.filterCallingUid));
···
// 解析Activity信息,当有多个可供选择时在这里弹出选择框
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

synchronized (mService.mGlobalLock) {
···
// 启动Activity
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);
···
return res;
}
}

startActivityMayWait较为复杂,其中关键的几点都已经用注释标注,主要是通过解析Intent来获取将要启动的Activity信息。

ActivityStarter#startActivity

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
···
// 此处创建了一个ActivityRecord对象
// 同时会通过ActivityRecord和intent构建appToken
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}

......

final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);//4
.....
return res;
}

startActivity中有个关键点就是,将要启动的Activity的ActivityRecord对象在这里被创建。ActivityRecord构建的同时会根据ActivityRecord和intent创建一个appToken。appToken是一个IBinder对象,用于提供给WMS关联Window和Activity,后面文章会详细分析。startActivity调用了另一个startActivity的重载,继而调用到了startActivityUnchecked方法。

ActivityStarter#startActivityUnchecked

frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {

// 设置初始状态值,这里的r赋值给mStartActivity
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor);
// 计算启动task的标志位Flag
// 主要处理一些Intent Flag冲突、复用问题
// 以及SingleInstance和SingleTask的处理
computeLaunchingTaskFlags();

// 通过sourceActivity计算sourceTask
// 主要处理 FLAG_ACTIVITY_NEW_TASK 问题
computeSourceStack();

mIntent.setFlags(mLaunchFlags);

// 寻找是否有可以复用的ActivityRecord
ActivityRecord reusedActivity = getReusableIntentActivity();
···
if (mReusedActivity != null) {
···
// 将当前栈移至前台
mReusedActivity = setTargetStackAndMoveToFrontIfNeeded(mReusedActivity);
      ···
setTaskFromIntentActivity(mReusedActivity);

if (!mAddingToTask && mReuseTask == null) {
resumeTargetStackIfNeeded();
return START_TASK_TO_FRONT;
}
}
     ···
  //singleTop 或者singleInstance的处理
if (dontStart) {
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and the client said not to do
// anything if that is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
···
// 向已存在的Activity分发新的Intent
// 会回调其onNewIntent()方法
deliverNewIntent(top);
     ···
return START_DELIVERED_TO_TOP;
}

boolean newTask = false;
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTaskRecord() : null;
// 设置对应的task
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
newTask = true;
// intent设置了FLAG_ACTIVITY_NEW_TASK,新建task
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
} else if (mSourceRecord != null) {
// 设置sourceRecord所在栈,即standard启动模式
result = setTaskFromSourceRecord();
} else if (mInTask != null) {
// 指定了启动的taskAffinity,设置到对应的task中
result = setTaskFromInTask();
} else {
// 在当前焦点的task中启动,这种情况不会发生
result = setTaskToCurrentTopOrCreateNewTask();
}
if (result != START_SUCCESS) {
return result;
}
···
// mDoResume由外部传入,本次流程中为true
if (mDoResume) {
// 使用ActivityStaskSupervisor去显示该Activity
final ActivityRecord topTaskActivity =
mStartActivity.getTaskRecord().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
// If the activity is not focusable, we can't resume it, but still would like to
// make sure it becomes visible as it starts (this will also trigger entry
// animation). An example of this are PIP activities.
// Also, we don't want to resume activities in a task that currently has an overlay
// as the starting activity just needs to be in the visible paused state until the
// over is removed.
mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
// Go ahead and tell window manager to execute app transition for this activity
// since the app transition will not be triggered through the resume channel.
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
// 如果当前activity是可以获取焦点的但当前Stack没有获取焦点
if (mTargetStack.isFocusable()
&& !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
// 将对应Task移至前台
mTargetStack.moveToFront("startActivityUnchecked");
}
// 使栈顶activity可见,即resume状态
mRootActivityContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);
}
} else if (mStartActivity != null) {
mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord());
}
mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack);

mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(),
preferredWindowingMode, mPreferredDisplayId, mTargetStack);

return START_SUCCESS;
}

startActivityUnchecked主要处理任务栈相关,处理singleTop、singleInstance问题,计算Intent Flag,以及栈顶复用问题。接着调用了调用了RootActivityContainer的resumeFocusedStacksTopActivities方法。

RootActivityContainer#resumeFocusedStacksTopActivities

frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

......

boolean result = false;
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
// 使栈顶Activity可见(resume)
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}

.......

return result;
}

resumeFocusedStacksTopActivities方法中调用ActivityStack#resumeTopActivityUncheckedLocked启动栈顶的Activity。

ActivityStack#resumeTopActivityUncheckedLocked

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
return false;
}

boolean result = false;
try {
// 防止递归调用,确保只有一个Activity执行该方法
mInResumeTopActivity = true;
// resume栈顶Activity
result = resumeTopActivityInnerLocked(prev, options);

final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}

return result;
}

inResumeTopActivity用于保证每次只有一个Activity执行resumeTopActivityUncheckedLocked()操作。

ActivityStack#resumeTopActivityInnerLocked

frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java

1
2
3
4
5
6
7
8
9
10
11
12
13
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
···
// 获取栈顶未finish的activity
ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
···
if (next.attachedToProcess()) {
···
} else {
···
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
}

resumeTopActivityInnerLocked方法的逻辑非常复杂,主要是判断当前是否真的需要resume栈顶Activity。这里精简了一下,当我们的栈顶activity没有绑定到任何Application的时候,就会调用ActivityStackSupervisor#startSpecificActivityLocked,我们此时恰好就是这种情况。

ActivityStackSupervisor#startSpecificActivityLocked

frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// 通过ATMS获取目标进程的WindowProcessController对象
// WindowProcessController用于ActivityManager与WindowManager同步进程状态
// 如果wpc为空,则表示对应进程不存在或者未启动
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);

boolean knownToBeDead = false;
// 这里的hasThread表示的是IApplicationThread
if (wpc != null && wpc.hasThread()) {
try {
// 启动activity
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}

// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}

// 这里主要处理键盘锁问题
if (getKeyguardController().isKeyguardLocked()) {
r.notifyUnknownVisibilityLaunched();
}

try {
···
// 如果对应App进程还未启动
// 通过handler发送消息启动进程
// 这部分将在下文讨论
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}

realStartActivityLocked中将会真正启动一个Activity。

ActivityStackSupervisor#realStartActivityLocked

frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java

realStartActivityLocked方法中创建了一个启动Activity事务,并利用IApplicationThread发送到目标App中,精简后的代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
···
// 创建一个启动Activity事务.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);

final DisplayContent dc = r.getDisplay().mDisplayContent;
// 添加Callback,注意这里创建的是LaunchActivityItem
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));

// 设置此次事务应该执行的最终状态
// 此次流程将会设置为resume,表示activity应该执行到onResume状态
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);

// 执行事务
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
···
return true;
}

从Android 8.0开始Activity的启动将会通过事务来完成,事务将会通过目标App的IApplicationThread远程发送到目标App中,然后通过ClientLifecycleManager 来执行。至此ATMS中执行的逻辑就结束了,剩下的就是目标App的ApplicationThread来执行目标Activity的各个生命周期方法了。

小结

同样的来回顾一下ATMS所做的工作。

  • 首先ATMS会判断权限信息,只有具有权限的调用进程才可以启动Activity。
  • 接着ActivityStarter解析Intent的内容,创建对应的ActivityRecord对象,根据是否需要新建Task来新建或者选择对应的TaskRecord添加Activity,并处理Task相关状态信息,例如前后台的转移。
  • 然后就会使前台Task的栈顶Activity可见,这个过程就会启动对应的Activity,必要情况会启动对应的进程。
  • 最后通过IPC调用将启动Activity的事务发送到对应进程中,交由对应App来处理。

这部分的时序图如下所示。

ATMS执行时序图

ActivityThread启动Activity过程

经过ATMS的一系列调用后,Activity启动工作终于来到了目标App进程中。

所谓的目标进程,是指目标Activity所在的进程。它与原Activity属于同一进程,也就是App内的Activity启动;也有可能属于另外一个App,这种情况属于跨App启动Activity。

不管是在App内启动还是跨App启动,其流程是一致的,都是由ApplicationThread接收到Binder通信传递过来的事务开始执行。

ApplicationThread#scheduleTransaction

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

1
2
3
4
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}

ApplicationThread#scheduleTransaction调用了ActivityThread#scheduleTransaction将事务交给主线程处理,ActivityThread#scheduleTransaction方法定义在其父类ClientTransactionHandler中。

ClientTransactionHandler#scheduleTransaction

frameworks/base/core/java/android/app/ClientTransactionHandler.java

1
2
3
4
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

这里调用sendMessage方法往主线程发送了一条what为ActivityThread.H.EXECUTE_TRANSACTION的消息,并将事务传递。

ActivityThread#sendMessage

ApplicationThread运行在Binder线程,与ActivityThread通信需经过Handler,而H是ActivityThread中的一个内部类,它继承自Handler,当ActivityThread调用sendMessage方法时其实就是在调用H#sendMessage。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) {
Slog.v(TAG,
"SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
}
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}

H#handleMessage

现在我们知道H是Handler的话,就知道消息一定在其handlerMessage方法中进行处理,来看看对应的消息是如何处理的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
// 省略一些case
···
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
// 省略一些case
···
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}

其中使用TransactionExecutor#execute来执行事务。

TransactionExecutor#execute

TransactionExecutor是专门用于处理事务的类,用于保证事务以正确的顺序执行。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
// ActivityRecord中的appToken
final IBinder token = transaction.getActivityToken();
···
if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
// 执行所有Callback
executeCallbacks(transaction);
// 执行到对应生命周期
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}

之前我们在ActivityStackSupervisor中创建事务并且通过addCallback的的方式将其添加到ClientTransaction中,现在调用executeCallbacks来执行每个Callback。

TransactionExecutor#executeCallbacks

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
// 快速返回路径
return;
}
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");

final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
: UNDEFINED;
// Index of the last callback that requests some post-execution state.
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED) {
// 这个方法可以平滑的执行生命周期
cycleToPath(r, closestPreExecutionState, transaction);
}
// 执行item的execute方法
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
if (r == null) {
// Launch activity request will create an activity record.
r = mTransactionHandler.getActivityClient(token);
}

if (postExecutionState != UNDEFINED && r != null) {
// Skip the very last transition and perform it by explicit state request instead.
final boolean shouldExcludeLastTransition =
i == lastCallbackRequestingState && finalState == postExecutionState;
cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
}
}
}

上节代码我们知道启动Activity时创建的ClientTransactionItem为LaunchActivityItem,后面将执行它的execute方法。

LaunchActivityItem#execute

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

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken);
// 处理启动Activity前的事项
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

client是ActivityThread,方法中调用ActivityThread#handleLaunchActivity来启动Activity。

ActivityThread#handleLaunchActivity

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

1
2
3
4
5
6
7
8
9
10
11
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
···
// 初始化WindowManager
WindowManagerGlobal.initialize();
···
// 启动Activity
final Activity a = performLaunchActivity(r, customIntent);
···
return a;
}

Activity启动的核心代码都在performLaunchActivity方法里。

ActivityThread#performLaunchActivity

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
···
// 为Activity创建Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 反射创建Activity对象
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}

try {
// 获取Application实例
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
···
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
// 调用activity.attach进行初始化
// 建立Context与Activity的联系,Window将会在这里创建
// 后面会出文章详解
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.configCallback,
r.assistToken);

···
// 回调onCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
// 更新LifeCycle状态
r.setState(ON_CREATE);
···
return activity;
}

至此Activity就已经被成功创建,并执行了其生命周期相关方法。

小结

Activity真正的启动工作在其对应的App中进行,主要有几个步骤:

  • ApplicationThread接收到ATMS发送过来的事务,通过Handler发送到主线程处理。
  • ActivityThread内部Handler(H)处理消息,并将事务交给TransactionExecutor处理。
  • TransactionExecutor执行事务的所有Callback,继而执行ActivityThread#handleLaunchActivity。
  • ActivityThread#handleLaunchActivity调用performLaunchActivity方法来执行核心逻辑。
  • ActivityThread#performLaunchActivity中反射创建的Activity实例,并且调用了attach方法绑定一些信息,然后调用callActivityOnCreate执行Activity生命周期。

这部分的时序图如下所示。

目标进程启动Activity过程时序图

总结

本文基于Android API 29源码分析了Activity的启动流程。整个过程涉及了四个进程和三次IPC调用,这四个进程分别是Launcher进程SystemServer进程应用程序进程、以及可能参与的Zygote进程,三次IPC调用又分为两次Binder调用和一次Socket调用。

我们来总结一下这几个过程的工作:

  1. Launcher进程:通过点击图标生成Intent,使用Binder通信通知ATMS启动对应Activity。
  2. SystemServer进程:
    • 检查调用(Launcher)进程是否被隔离、是否有权限启动Activity,然后生成ActivityStarter来处理Activity启动事宜。
    • 解析Intent中的信息,通过这些信息解析出包含Activity信息的ActivityInfo对象。判断Activity是否有在清单文件中注册、是否有权限等。
    • 计算Intent的Flags,处理LaunchMode问题,判断Activity的目标任务栈,将Activity添加到任务栈中。
    • 将任务栈移至前台,使栈顶的Activity可见,会创建一个事务并通过Binder调用发送到目标App进程。
    • 如果App进程不存在,通过Socket通知Zygote进程启动App进程。
  3. 应用程序进程:
    • 接收SystemServer传递的事务并且执行事务。
    • 反射创建Activity对象,为Activity创建Context、Window等。
    • 回调其onCreate、onStart、onResume生命周期。
  4. Zygote进程:接收SystemServer的消息通过Fork自身来创建App进程,这部分将会在下篇文章详细讨论。

Launcher进程负责通知ATMS发起Activity启动;SystemServer进程中参与的主要是ATMS服务,它负责计算构造目标的Intent、处理TaskRecord和ActivityRecord信息、以及ActivityStack的处理,最后将启动消息发送到对应应用程序进程;应用程序进程负责接收ATMS发送过来的事务并处理,Activity的创建以及生命周期的回调都在这里处理。

若应用程序进程还未启动,Zygote进程还需要参与进来创建对应进程。

下篇文章将会继续分析Zygote进程创建目标App进程的过程。

参考