【Android 13源码分析】Activity启动流程-2

对WMS很感兴趣,所以决定以在桌面点击应用图标,到应用的Activity显示到屏幕上,这一简单操作为基础,分析整个过程。

其中涉及到非常多的模块,但是首先需要分析的就是Activity的启动流程,由于篇幅原因,分为以下3部分:

【Android 13源码分析】Activity启动流程-1

【Android 13源码分析】Activity启动流程-2

【Android 13源码分析】Activity启动流程-3

虽然整个操作实际上就2S时间,但是整个完整的流程分析下来也需要几个月,而且还是仅仅是启动主流程,

这三篇对Activity启动流程分析只关心主流程,不看具体细节,当然对于一些关键方法会着重介绍,这样以后如果有遇到相关问题的修改可以通过这篇笔记找到具体代码位置,然后根据具体的问题分析修改。

后续会有在Activity启动流程基础上延伸出来的各个分支的记录,比如窗口的创建与挂载,Surface相关,窗口的动画等待,这些流程的分析都需要基于Activity启动流程。

启动Activity的方式有很多,当前以在Launch中点击“电话”图标启动应用为例,本篇为第二篇。

【Android 13源码分析】Activity启动流程-1在ActivityStarer::startActivityInner方法中,通过getOrCreateRootTask方法创建Task,而后通过setNewTask方法将新建的ActivityRecord进行挂在到新建的Task上,接下来将需要处理新的Activity启动和显示逻辑。

后续的流程由resumeFocusedTasksTopActivities执行。

显示Activity resumeFocusedTasksTopActivities

调用链

1
2
3
4
5
6
7
8
9
10
11
arduino复制代码RootWindowContainer::resumeFocusedTasksTopActivities
Task::resumeTopActivityUncheckedLocked
Task::resumeTopActivityInnerLocked
TaskFragment::resumeTopActivity
TaskDisplayArea::pauseBackTasks -- 2.2.1 pause LauncherActivity
WindowContainer::forAllLeafTask
TaskFragment::forAllLeafTaskFragments
TaskFragment::startPausing
TaskFragment::startPausing
TaskFragment::schedulePauseActivity --构建 PauseActivityItem,这里是触发暂停launch
ActivityTaskManagerService::startProcessAsync -- 2.2.2创建“电话”进程

主流程跟踪

经过几次调用会执行到TaskFragment::resumeTopActivity方法,这个方法非常复杂,场景不同执行的分支也不同,值得重点分析。而且很多重要的逻辑都集中在这里,我觉得后续会被重构的。
当前还是只分析launcher 启动“电话”的场景

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
java复制代码# TaskFragment
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
// 这里的next返回的是 电话的main activity,表示下一个需要现实的
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
......
// 如果跳过的这些逻辑都没执行return,则正在开始执行 resume流程,打印关键日志。
// 前面流程如果返回也有响应日志的打印
// 打印日志,需要显示哪个Activity
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
......
// 重点* 1. 这里会将 launch的Activity pause 。参数是 电话的ActivityRecord
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
......
if (pausing) {
ProtoLog.v(WM_DEBUG_STATES, "resumeTopActivity: Skip resume: need to"+ " start pausing");
if (next.attachedToProcess()) {
......
} else if (!next.isProcessRunning()) {
// 重点*2. 进程没有运行,则触发异步创建进程。 当前逻辑肯定是执行这一条
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
}
......
// 注意,这里会return,
return true;
}
......
//后面还有重要逻辑,当前可忽略
}

重点分析:
上面说过这个函数非常复杂,在当前逻辑有2个主线

  1. pause当前Activity,也就是launcher
  2. 异步创建“电话”的进程

在第一步将launcher的Activity执行pauser, 这一步执行到最后也会触发”电话”应用MainActivity的启动,第二步创建“电话”进程,进程创建完肯定也会执行”电话”应用MainActivity的启动,这么看来就有2个地方触发了。

这是因为是异步创建进程,不知道谁先执行完,但是可以明确的是,”电话”应用MainActivity必须有2个条件:

  1. 前一个Activity执行完pause
  2. 进程创建完成

所以无论2个分支哪一个先执行完,都需要等后一个执行完的来触发后续电话”应用MainActivity的启动。

先看launcher的pause流程

  1. pause 流程 pauseBackTasks

需要显示新的Activity,那么之前的肯定是要执行pause的,就在这里执行。参数next为“电话的”ActivityRecord

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
java复制代码# TaskDisplayArea

// 可以看到“电话”ActivityRecord在这里就被称为resuming
boolean pauseBackTasks(ActivityRecord resuming) {
final int[] someActivityPaused = {0};
forAllLeafTasks(leafTask -> {
// Check if the direct child resumed activity in the leaf task needed to be paused if
// the leaf task is not a leaf task fragment.
if (!leafTask.isLeafTaskFragment()) {
// 当前不会走这里
final ActivityRecord top = topRunningActivity();
final ActivityRecord resumedActivity = leafTask.getResumedActivity();
if (resumedActivity != null && top.getTaskFragment() != leafTask) {
// Pausing the resumed activity because it is occluded by other task fragment.
if (leafTask.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
someActivityPaused[0]++;
}
}
}

leafTask.forAllLeafTaskFragments((taskFrag) -> {
final ActivityRecord resumedActivity = taskFrag.getResumedActivity();
if (resumedActivity != null && !taskFrag.canBeResumed(resuming)) {
if (taskFrag.startPausing(false /* uiSleeping*/, resuming, "pauseBackTasks")) {
someActivityPaused[0]++;
}
}
}, true /* traverseTopToBottom */);
}, true /* traverseTopToBottom */);
return someActivityPaused[0] > 0;
}

forAllLeafTasks和forAllLeafTaskFragments在【WMS/AMS 常见方法调用提取】中有解释,那么当前这段方法其实就是让DefaultTaskDisplayArea下的每个叶子LeafTaskFragments执行startPausing。

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
typescript复制代码# TaskFragment
boolean startPausing(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming,
String reason) {
......
// 日志输出当前TaskFragment和mResumedActivity的关系。后面会贴上日志证明
ProtoLog.d(WM_DEBUG_STATES, "startPausing: taskFrag =%s " + "mResumedActivity=%s", this,
mResumedActivity);
......
// 后面的prev就是launcher的ActivityRecord了
ActivityRecord prev = mResumedActivity;
......
// 输出日志
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSING: %s", prev);
mPausingActivity = prev;
mLastPausedActivity = prev;
if (!prev.finishing && prev.isNoHistory()
&& !mTaskSupervisor.mNoHistoryActivities.contains(prev)) {
mTaskSupervisor.mNoHistoryActivities.add(prev);
}
// 设置window状态为PAUSING
prev.setState(PAUSING, "startPausingLocked");
prev.getTask().touchActiveTime();
......
if (prev.attachedToProcess()) {
// launcher的进程肯定是满足条件的
if (shouldAutoPip) {
boolean didAutoPip = mAtmService.enterPictureInPictureMode(
prev, prev.pictureInPictureArgs);
ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
+ "directly: %s, didAutoPip: %b", prev, didAutoPip);
} else {
// 重点*1. 根据堆栈是执行这里。上面的PIP日志没输出,也能确定是走的这个
schedulePauseActivity(prev, userLeaving, pauseImmediately, reason);
}
}
......
}

void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, String reason) {
// 输出日志
ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
try {
// 输出events 日志
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving, reason);
// 重点构建并执行PauseActivityItem
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
}
}

最终在TaskFragment::schedulePauseActivity构建并执行了launcher的pause事件。
这块相关的日志输入如图:
因为是后面补充的所以对象不一样,但是能确定这里处理的TaskFragment和mResumedActivity都是launcher对象的。

Plotolog-startPausing.png

tip:
State movement这段的输出是在ActivityRecord::setState 只有状态改变都会输出

接下来的重点是看PauseActivityItem的执行逻辑

1.1 PauseActivityItem

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
typescript复制代码# PauseActivityItem

@Override
public void execute(ClientTransactionHandler client, ActivityClientRecord r,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
// 重点*1. 触发 handlePauseActivity 流程
client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

@Override
public int getTargetState() {
return ON_PAUSE;
}
// pauser执行后调用 postExecute
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mDontReport) {
return;
}
// 重点*2. 触发启动新的Activity
ActivityClient.getInstance().activityPaused(token);
}

默认已经知道ClientTransaction调用逻辑,不知道移步【】
这里先执行execute 的逻辑,也就是 launcher的pause流程,这个不是主线,单独解释【】。然后执行postExecute。这里会触发新Activity的启动。

1
2
3
4
5
6
7
8
9
scss复制代码# ActivityClient

public void activityPaused(IBinder token) {
try {
getActivityClientController().activityPaused(token);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
}

getActivityClientController返回的是ActivityClientController对象。

调用链

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
arduino复制代码ActivityClientController::activityPaused
ActivityRecord::activityPaused
TaskFragment::completePause
RootWindowContainer::resumeFocusedTasksTopActivities --分支1 ,再次执行 resumeFocusedTasksTopActivities
RootWindowContainer::resumeFocusedTasksTopActivities
Task::resumeTopActivityUncheckedLocked
Task::resumeTopActivityInnerLocked
TaskFragment::resumeTopActivity
ActivityTaskSupervisor::startSpecificActivity --触发 startSpecificActivity 判断应用是否创建
RootWindowContainer::ensureActivitiesVisible --分支2
RootWindowContainer::ensureActivitiesVisible
DisplayContent::ensureActivitiesVisible
WindowContainer::forAllRootTasks --忽略固定逻辑
Task::ensureActivitiesVisible
Task::forAllLeafTasks --忽略固定逻辑
TaskFragment::updateActivityVisibilities
EnsureActivitiesVisibleHelper::process
EnsureActivitiesVisibleHelper::setActivityVisibilityState
EnsureActivitiesVisibleHelper::makeVisibleAndRestartIfNeeded
ActivityTaskSupervisor::startSpecificActivity --触发 startSpecificActivity 判断应用是否创建

调用堆栈如下:

pause-startProcessAsync.png

不是每个函数都要去跟,没有意义,跟踪重点函数,关注重点处理的地方即可。 否则下个版本重构后,就完全不一样。 所以只需要记住重点做的事情就好。
这边又2个地方都会出发ActivityTaskSupervisor::startSpecificActivity,而且都是由ActivityClientController::activityPaused为源头。
由activityPaused方法名也能知道这段逻辑是在launcher 执行完pause后再执行的

注意这里在第一个分支 RootWindowContainer::resumeFocusedTasksTopActivities到TaskFragment::resumeTopActivity直接的调用栈和上一篇是一样的,只不过最后执行的不一样而已

pause后,虽然又2个分支,但是根据函数名,其实都是为了能让下一个Activity可见。毕竟不能让用户什么都看不见, 总得显示一个吧

主流程跟踪

接下来进入代码分析

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
typescript复制代码# ActivityRecord
void activityPaused(boolean timeout) {
......
if (pausingActivity == this) {
// 打印日志
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
(timeout ? "(due to timeout)" : " (pause complete)"));
mAtmService.deferWindowLayout();
try {
// 进入下一步,注入第二个参数为null
taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
} finally {
mAtmService.continueWindowLayout();
}
return;
}
......
}
// 打印如下
WindowManager: Moving to PAUSED: ActivityRecord{1f58beb u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t8} (pause complete)

//TaskFragment::completePause
# TaskFragment
@VisibleForTesting
void completePause(boolean resumeNext, ActivityRecord resuming) {
// 拿到先去的Activity,也就是需要 pause的
ActivityRecord prev = mPausingActivity;
ProtoLog.v(WM_DEBUG_STATES, "Complete pause: %s", prev);
if (prev != null) {
......
// 设置窗口状态为PAUSED
prev.setState(PAUSED, "completePausedLocked");
if (prev.finishing) {
...... 如果已经finish,上面还在设置 pause,那正常应该是还没finish
} else if (prev.hasProcess()) {
// 打印状态日志
ProtoLog.v(WM_DEBUG_STATES, "Enqueue pending stop if needed: %s "
+ "wasStopping=%b visibleRequested=%b", prev, wasStopping,prev.mVisibleRequested);
}else {
......
}
if (resumeNext) {
......
// 重点* 1. 第1个分支
mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,null /* targetOptions */);
......
}
......
// 重点* 2.
mRootWindowContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
......
}
}

结合前面TaskFragment::resumeTopActivity的创建进程,然后根据堆栈知道这2个分支也也创建新进程,那已知3地方触发创建进程。

这里的 topRootTask 就是SourceActivity“电话”的Activity,prev是launcher的,resuming为null。

1.1.1 分支1 resumeFocusedTasksTopActivities

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
arduino复制代码# TaskFragment
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
......
// pause
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
......
if (pausing) {
......
// 启动进程
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? HostingRecord.HOSTING_TYPE_NEXT_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_NEXT_ACTIVITY);
......
//return,
return true;
}
// 本次逻辑走这
......
// pause 逻辑会再次走到这,新进程目前还没有启动所以走else
if (next.attachedToProcess()) {
......
} else {
......
// 打印log
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivity: Restarting %s", next);
// 重点* 执行startSpecificActivity
mTaskSupervisor.startSpecificActivity(next, true, true);
}
}

又是TaskFragment::resumeTopActivity方法,这次是直接走到这个方法的最下面,启动Activity。

1.1.2 ensureActivitiesVisible分支

看方法名是为了 Activity的可见
根据上面的调用链,会执行到 DisplayContent::ensureActivitiesVisible

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
scss复制代码# DisplayContent
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
if (mInEnsureActivitiesVisible) {
// Don't do recursive work.
return;
}
mInEnsureActivitiesVisible = true;
mAtmService.mTaskSupervisor.beginActivityVisibilityUpdate();
try {
forAllRootTasks(rootTask -> {
rootTask.ensureActivitiesVisible(starting, configChanges, preserveWindows,
notifyClients);
});
if (mTransitionController.isCollecting()
&& mWallpaperController.getWallpaperTarget() != null) {
// Also update wallpapers so that their requestedVisibility immediately reflects
// the changes to activity visibility.
// TODO(b/206005136): Move visibleRequested logic up to WindowToken.
mWallpaperController.adjustWallpaperWindows();
}
} finally {
mAtmService.mTaskSupervisor.endActivityVisibilityUpdate();
mInEnsureActivitiesVisible = false;
}
}

这里拿出来主要是遇到了forAllRootTasks这个方法,其实就和之前的forAllLeafTasks使用方式是一样的。对每个rootTask执行Lambda而已。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
java复制代码# Task
void ensureActivitiesVisible(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
mTaskSupervisor.beginActivityVisibilityUpdate();
try {
forAllLeafTasks(task -> {
task.updateActivityVisibilities(starting, configChanges, preserveWindows,
notifyClients);
}, true /* traverseTopToBottom */);

if (mTranslucentActivityWaiting != null &&
mUndrawnActivitiesBelowTopTranslucent.isEmpty()) {
// Nothing is getting drawn or everything was already visible, don't wait for
// timeout.
notifyActivityDrawnLocked(null);
}
} finally {
mTaskSupervisor.endActivityVisibilityUpdate();
}
}

这里又有个forAllLeafTasks,调用每个叶子Task的updateActivityVisibilities方法,但是Task的这个方法是气父类TaskFragmet里定义的,所以看TaskFragmet。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
java复制代码# TaskFragmet
private final EnsureActivitiesVisibleHelper mEnsureActivitiesVisibleHelper =
new EnsureActivitiesVisibleHelper(this);
final void updateActivityVisibilities(@Nullable ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
mTaskSupervisor.beginActivityVisibilityUpdate();
try {
// 重点
mEnsureActivitiesVisibleHelper.process(
starting, configChanges, preserveWindows, notifyClients);
} finally {
mTaskSupervisor.endActivityVisibilityUpdate();
}
}

我们知道这一条线都是为了处理Activity可见的。 在这定义了一个专门的类来处理。
不过需要注意的是,这个方法会执行多次,因为他是遍历每一个符合条件的子容器,从上到下遍历。

1.1.3 EnsureActivitiesVisibleHelper::process

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
java复制代码# EnsureActivitiesVisibleHelper
void process(@Nullable ActivityRecord starting, int configChanges, boolean preserveWindows, boolean notifyClients) {
// 调用 reset 方法,对传入的参数进行重置处理
reset(starting, configChanges, preserveWindows, notifyClients);
......
for (int i = mTaskFragment.mChildren.size() - 1; i >= 0; --i) {
// 获取当前子元素
final WindowContainer child = mTaskFragment.mChildren.get(i);
// 将当前子元素转换为TaskFragment,只有TaskFragment重写了,Task或ActivityRecord为null
// Task的孩子一般就是ActivityRecord或者Task
final TaskFragment childTaskFragment = child.asTaskFragment();
if (childTaskFragment != null
&& childTaskFragment.getTopNonFinishingActivity() != null) {
......
} else {
// 只有ActivityRecord重写了
setActivityVisibilityState(child.asActivityRecord(), starting, resumeTopActivity);
}
}
}

private void setActivityVisibilityState(ActivityRecord r, ActivityRecord starting,
final boolean resumeTopActivity) {
......
if (reallyVisible) {
.......
if (!r.attachedToProcess()) {
// 主流程
makeVisibleAndRestartIfNeeded(mStarting, mConfigChanges, isTop,
resumeTopActivity && isTop, r);
} else {
......
}
} else {
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "Make invisible? " + r
+ " finishing=" + r.finishing + " state=" + r.getState()
+ " containerShouldBeVisible=" + mContainerShouldBeVisible
+ " behindFullyOccludedContainer=" + mBehindFullyOccludedContainer
+ " mLaunchTaskBehind=" + r.mLaunchTaskBehind);
}
// 不可见调用makeInvisible
r.makeInvisible();
}

}

这里的r 表示需要启动的ActivityRecord,当前流程还是onPause的流程。并没有知道创建进程那一步,所以进程是没有attached的。那就会执行makeVisibleAndRestartIfNeeded

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
arduino复制代码# EnsureActivitiesVisibleHelper
private void makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
boolean isTop, boolean andResume, ActivityRecord r) {
......
if (!r.mVisibleRequested || r.mLaunchTaskBehind) {
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
}
// 设置Visibility
r.setVisibility(true);
}
if (r != starting) {
mTaskFragment.mTaskSupervisor.startSpecificActivity(r, andResume,
true /* checkConfig */);
}
}

1.1.4 ActivityTaskSupervisor::startSpecificActivity

这个方法也被调用了2次

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
java复制代码# ActivityTaskSupervisor

void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
// 拿到目标进程信息
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);

boolean knownToBeDead = false;
// 进程是否存在,且主线程已执行
if (wpc != null && wpc.hasThread()) {
try {
// 进程进程 则执行 realStartActivityLocked 流程
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);1111111111
}
......
}
......
// 异步启动进程
mService.startProcessAsync(r, knownToBeDead, isTop,
isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_ACTIVITY);
}

这里有2个分支,如果目标进程创建了,则走realStartActivityLocked,否则执行创建的逻辑。不过就目前2个调用的地方都是执行onPause的逻辑性,这里还是其实都是制作到startProcessAsync。 而不会走进realStartActivityLocked

2 创建进程逻辑

这里是回到执行pause的同级流程,也就是最前面的TaskFragment::resumeTopActivity
执行pause后会执行 ActivityTaskManagerService::startProcessAsync,最后也是通过 ActivityManagerService来触发启动进程的。
看看AMS这块执行进程创建的调用流程

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
java复制代码# ATMS  
void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
String hostingType) {
try {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "dispatchingStartProcess:"
+ activity.processName);
}
// 发生消息,启动进程,调用ActivityManagerInternal::startProcess
final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
isTop, hostingType, activity.intent.getComponent());
mH.sendMessage(m);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
// ActivityManagerInternal::startProcess 的实现在AMS的内部类 LocalService 中
# AMS.LocalService
public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
boolean isTop, String hostingType, ComponentName hostingName) {
try {
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "startProcess:"
+ processName);
}
synchronized (ActivityManagerService.this) {
// 重点调用
startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
new HostingRecord(hostingType, hostingName, isTop),
ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
false /* isolated */);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
@GuardedBy("this")
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
boolean isolated) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
false /* isSdkSandbox */, 0 /* sdkSandboxClientAppUid */,
null /* sdkSandboxClientAppPackage */,
null /* ABI override */, null /* entryPoint */,
null /* entryPointArgs */, null /* crashHandler */);
}

# ProcessList
boolean startProcessLocked(......) {
......
mService.mProcStartHandler.post(() -> handleProcessStart(
app, entryPoint, gids, runtimeFlags, zygotePolicyFlags, mountExternal,
requiredAbi, instructionSet, invokeWith, startSeq));
......
}
private void handleProcessStart(......) {
创建一个用于启动进程的 Runnable 对象
final Runnable startRunnable = () -> {
try { // 调用 startProcess 方法启动进程,并获取启动结果 ProcessStartResult
final Process.ProcessStartResult startResult = startProcess(app.getHostingRecord(),
entryPoint, app, app.getStartUid(), gids, runtimeFlags, zygotePolicyFlags,
mountExternal, app.getSeInfo(), requiredAbi, instructionSet, invokeWith,
app.getStartTime());
// 在锁定 ActivityManagerService 后,处理进程启动结果
synchronized (mService) {
handleProcessStartedLocked(app, startResult, startSeq);
}
} catch (RuntimeException e) {
......异常处理
}
};
// // 如果有前任进程并且前任进程正在死亡中
final ProcessRecord predecessor = app.mPredecessor;
if (predecessor != null && predecessor.getDyingPid() > 0) {
// 通过前任进程执行启动进程的 Runnable 对象
handleProcessStartWithPredecessor(predecessor, startRunnable);
} else {
// 如果没有前任进程或前任进程未死亡,直接运行启动进程的 Runnable 对象
// 走的是这个逻辑
startRunnable.run();
}
}

通过 startProcess 来启动应用进程

执行完后输出日志

1
ruby复制代码07-26 19:19:05.477  8737  8782 I ActivityManager: Start proc 19643:com.example.myapplication/u0a198 for next-top-activity {com.example.myapplication/com.example.myapplication.MainActivity}

这段日志是在 ProcessList::handleProcessStart 方法里构建了个StringBuilder,然后传递给AMS::reportUidInfoMessageLocked进行打印的。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%