了解了WMS窗口层级结构之后,试着从WMS的角度来分析activity启动流程。
1. 创建窗口层级结构树的节点
1.1 分析窗口层级变化
从launcher启动一个app,启动前的窗口层级:

启动后的窗口层级:

可以看到启动之后,DefaultTaskDisplayArea下面多了一套层级Task 11 -- ActivityRecord -- windowState,
那么是如何添加的呢,我们还是在WindowContainer.java的2个addChild函数中添加log来跟踪调用信息:
java
// WindowContainer.java
protected void addChild(E child, Comparator<E> comparator) {
if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken
|| child instanceof WindowState) {
android.util.Log.d("Test111", this + " add child " + child, new Exception());
}
...
}
void addChild(E child, int index) {
if (child instanceof Task || child instanceof ActivityRecord || child instanceof WindowToken
|| child instanceof WindowState) {
android.util.Log.d("Test111", this + " add child2 " + child, new Exception());
}
...
}
java
D Test111 : DefaultTaskDisplayArea@236455599 add child2 Task{6dcada9 #11 type=standard ?? U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
D Test111 : java.lang.Exception
D Test111 : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:552)
D Test111 : at com.android.server.wm.TaskDisplayArea.addChildTask(TaskDisplayArea.java:383)
D Test111 : at com.android.server.wm.TaskDisplayArea.addChild(TaskDisplayArea.java:369)
D Test111 : at com.android.server.wm.Task$Builder.build(Task.java:6611)
D Test111 : at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:1133)
D Test111 : at com.android.server.wm.TaskDisplayArea.getOrCreateRootTask(TaskDisplayArea.java:1158)
D Test111 : at com.android.server.wm.RootWindowContainer.getLaunchRootTask(RootWindowContainer.java:2982)
D Test111 : at com.android.server.wm.ActivityStarter.getLaunchRootTask(ActivityStarter.java:2901)
D Test111 : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1766)
D Test111 : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
D Test111 : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
D Test111 : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
D Test111 : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5119)
D Test111 : at android.os.Binder.execTransactInternal(Binder.java:1179)
D Test111 : at android.os.Binder.execTransact(Binder.java:1143)
D Test111 : Task{6dcada9 #11 type=standard A=10107:com.example.mytestapplication U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0} add child2 ActivityRecord{5297b65 u0 com.example.mytestapplication/.MainActivity
D Test111 : java.lang.Exception
D Test111 : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:552)
D Test111 : at com.android.server.wm.TaskFragment.addChild(TaskFragment.java:1693)
D Test111 : at com.android.server.wm.Task.addChild(Task.java:1448)
D Test111 : at com.android.server.wm.ActivityStarter.addOrReparentStartingActivity(ActivityStarter.java:2832)
D Test111 : at com.android.server.wm.ActivityStarter.setNewTask(ActivityStarter.java:2784)
D Test111 : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1771)
D Test111 : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
D Test111 : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
D Test111 : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
D Test111 : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
D Test111 : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5119)
D Test111 : at android.os.Binder.execTransactInternal(Binder.java:1179)
D Test111 : at android.os.Binder.execTransact(Binder.java:1143)
D Test111 : ActivityRecord{5297b65 u0 com.example.mytestapplication/.MainActivity t11} add child Window{c52dc92 u0 Splash Screen com.example.mytestapplication}
D Test111 : java.lang.Exception
D Test111 : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:517)
D Test111 : at com.android.server.wm.WindowToken.addWindow(WindowToken.java:321)
D Test111 : at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:3938)
D Test111 : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1778)
D Test111 : at com.android.server.wm.Session.addToDisplayAsUser(Session.java:204)
D Test111 : at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:646)
D Test111 : at com.android.server.wm.Session.onTransact(Session.java:170)
D Test111 : at android.os.Binder.execTransactInternal(Binder.java:1184)
D Test111 : at android.os.Binder.execTransact(Binder.java:1143)
D Test111 : ActivityRecord{5297b65 u0 com.example.mytestapplication/.MainActivity t11} add child Window{edc9045 u0 com.example.mytestapplication/com.example.mytestapplication.MainActivity}
D Test111 : java.lang.Exception
D Test111 : at com.android.server.wm.WindowContainer.addChild(WindowContainer.java:517)
D Test111 : at com.android.server.wm.WindowToken.addWindow(WindowToken.java:321)
D Test111 : at com.android.server.wm.ActivityRecord.addWindow(ActivityRecord.java:3938)
D Test111 : at com.android.server.wm.WindowManagerService.addWindow(WindowManagerService.java:1778)
D Test111 : at com.android.server.wm.Session.addToDisplayAsUser(Session.java:204)
D Test111 : at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:646)
D Test111 : at com.android.server.wm.Session.onTransact(Session.java:170)
D Test111 : at android.os.Binder.execTransactInternal(Binder.java:1179)
D Test111 : at android.os.Binder.execTransact(Binder.java:1143)
rootTask.minimalResumeActivityLocked(r);
从Log打印看,先创建Task,然后创建ActivityRecord,最后创建WindowState,
launcher从调用startActivity开始,经过ActivityTaskManagerService.java的startActivity,到ActivityStarter.java
java
// ActivityStarter.java
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...
if (mTargetRootTask == null) {
// 1
mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
if (newTask) {
// 2
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
addOrReparentStartingActivity(targetTask, "adding to task");
}
// 3
if (newTask) {
EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
}
mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask)
...
}
-
创建Task,参考下面1.2
-
创建ActivityRecord1.3
-
分别输出event log:
javawm_create_task: [0,27] wm_create_activity[0,268082872,27,com.example.mytestapplication/.MainActivity,android.intent.action.MAIN,NULL,NULL,270532608]
1.2 创建Task
调用到RootWindowContainer.java的getLaunchRootTask,找到DefaultTaskDisplayArea,
在这里创建了Task 11, 并设置DefaultTaskDisplayArea为parent.
java
// TaskDisplayArea.java
Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop,
@Nullable Task candidateTask, @Nullable Task sourceTask,
@Nullable ActivityOptions options, int launchFlags) {
...
return new Task.Builder(mAtmService)
.setWindowingMode(windowingMode)
.setActivityType(activityType)
.setOnTop(onTop)
.setParent(this)
.setSourceTask(sourceTask)
.setActivityOptions(options)
.setLaunchFlags(launchFlags)
.build();
}
在Task的构造函数的最后,会输出event log: wm_task_created: [mTaskId,getRootTaskId]
1.3 创建ActivityRecord
回到ActivityStarter.java 的startActivityInner,在创建完Task之后,调用setNewTask,经过的调用又会走到下面函数:
java
// // ActivityStarter.java
private void addOrReparentStartingActivity(@NonNull Task task, String reason) {
TaskFragment newParent = task;
...
if (mStartActivity.getTaskFragment() == null
|| mStartActivity.getTaskFragment() == newParent) {
newParent.addChild(mStartActivity, POSITION_TOP);
} else {
mStartActivity.reparent(newParent, newParent.getChildCount() /* top */, reason);
}
}
mStartActivity: 是ActivityStarter.java 在executeRequest函数中创建的ActivityRecord对象,并一直传递到startActivityInner函数,在函数第一句调用setInitialState函数时,就将刚创建的ActivityRecord对象赋值给了mStartActivity。
newParent: 根据log推导,我们知道newParent就是刚创建的Task。
所以在这里将ActivityRecord挂在到Task上。
1.4 创建WindowState
再下面创建WindowState和挂载窗口层级的堆栈,看出来是app通过调用WMS的addToDisplayAsUser触发的,我们之前分析过,这部分是app在resume时候调用的,这个留在后面再说,我们先关注一下launcher的pause处理流程。
2. Pause
2.1 分析Pasue调用栈
在PauseActivityItem.java的obtain函数打log,看谁构造了PauseActivityItem
java
// PauseActivityItem.java
/** Obtain an instance initialized with provided params. */
public static PauseActivityItem obtain(boolean finished, boolean userLeaving, int configChanges,
boolean dontReport) {
PauseActivityItem instance = ObjectPool.obtain(PauseActivityItem.class);
if (instance == null) {
instance = new PauseActivityItem();
}
instance.mFinished = finished;
instance.mUserLeaving = userLeaving;
instance.mConfigChanges = configChanges;
instance.mDontReport = dontReport;
return instance;
}
log中的调用栈如下:
java
I Test111 : java.lang.Exception
I Test111 : at android.app.servertransaction.PauseActivityItem.obtain(PauseActivityItem.java:82)
I Test111 : at com.android.server.wm.TaskFragment.schedulePauseActivity(TaskFragment.java:1527)
I Test111 : at com.android.server.wm.TaskFragment.startPausing(TaskFragment.java:1469)
I Test111 : at com.android.server.wm.TaskFragment.startPausing(TaskFragment.java:1380)
I Test111 : at com.android.server.wm.TaskDisplayArea.lambda$pauseBackTasks$7(TaskDisplayArea.java:1478)
I Test111 : at com.android.server.wm.TaskDisplayArea$$ExternalSyntheticLambda4.accept(Unknown Source:6)
I Test111 : at com.android.server.wm.TaskFragment.forAllLeafTaskFragments(TaskFragment.java:1655)
I Test111 : at com.android.server.wm.TaskDisplayArea.lambda$pauseBackTasks$8$TaskDisplayArea(TaskDisplayArea.java:1475)
I Test111 : at com.android.server.wm.TaskDisplayArea$$ExternalSyntheticLambda6.accept(Unknown Source:8)
I Test111 : at com.android.server.wm.Task.forAllLeafTasks(Task.java:3185)
I Test111 : at com.android.server.wm.Task.forAllLeafTasks(Task.java:3173)
I Test111 : at com.android.server.wm.WindowContainer.forAllLeafTasks(WindowContainer.java:1781)
I Test111 : at com.android.server.wm.TaskDisplayArea.pauseBackTasks(TaskDisplayArea.java:1461)
I Test111 : at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1059)
I Test111 : at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5035)
I Test111 : at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4970)
I Test111 : at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2361)
I Test111 : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1842)
I Test111 : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
I Test111 : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
I Test111 : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
I Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
I Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
I Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
I Test111 : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
I Test111 : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5119)
I Test111 : at android.os.Binder.execTransactInternal(Binder.java:1179)
I Test111 : at android.os.Binder.execTransact(Binder.java:1143)
可以看出来在app流程走到startActivityInner中会触发launcher的pause处理。
2.1 sysytem server发起pause
java
// ActivityStarter.java
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...
if (mTargetRootTask == null) {
// 1
mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
if (newTask) {
// 2
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
addOrReparentStartingActivity(targetTask, "adding to task");
}
...
// 3
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
startActivityInner的 1, 2部分分别是Task的构造和挂载,以及ActivityRecord的构造和挂载,上面已经介绍。
3则是launcher的pause, 通过函数名可以推测,它应该还包括目标Activity的resume处理,但我们先只关注pause.
在调用到TaskDisplayArea.java的pauseBackTasks函数时:
java
boolean pauseBackTasks(ActivityRecord resuming) {
final int[] someActivityPaused = {0};
forAllLeafTasks((task) -> {
final ActivityRecord resumedActivity = task.getResumedActivity();
if (resumedActivity != null
&& (task.getVisibility(resuming) != TASK_VISIBILITY_VISIBLE
|| !task.isTopActivityFocusable())) {
ProtoLog.d(WM_DEBUG_STATES, "pauseBackTasks: task=%s "
+ "mResumedActivity=%s", task, resumedActivity);
if (task.startPausingLocked(false /* uiSleeping*/,
resuming, "pauseBackTasks")) {
someActivityPaused[0]++;
}
}
}, true /* traverseTopToBottom */);
return someActivityPaused[0] > 0;
}
forAllLeafTasks的真正实现在Task.java,这类写法我们之前在分析WMS时也经常见到,就是在WindowContainer.java以及它的子类中都会有实现,
但一般真正的处理,只在其中一个类中,目的就是递归每一个窗口层级节点。
java
// Task.java
void forAllLeafTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
final int count = mChildren.size();
boolean isLeafTask = true;
if (traverseTopToBottom) {
for (int i = count - 1; i >= 0; --i) {
final Task child = mChildren.get(i).asTask();
if (child != null) {
isLeafTask = false;
child.forAllLeafTasks(callback, traverseTopToBottom);
}
}
}
...
if (isLeafTask) callback.accept(this);
}
forAllLeafTasks的目的是找到leaf task,即:该Task的child是否还是task,如果是,就不是leaf task, 如果不是,就是leaf task,找到之后继续执行上面的
2.2 通知launcher pasue
pauseBackTasks,找到满足条件的activity, 从目前来看满足条件的只有一个,就是launcher, 调用startPausing,最终会调用ATMS,通知launcher pause
java
// TaskFragment.java
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, String reason) {
ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
try {
// 1
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving, reason);
// 2
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
} catch (Exception e) {
...
}
- 输出event log:
wm_pause_activity: [0,96028723,com.android.launcher3/.uioverrides.QuickstepLauncher,userLeaving=true,pauseBackTasks] prev.app.getThread(): 就是launcher的ApplicationThread,scheduleTransaction的第三个参数是new了一个PauseActivityItem,最后会通过binder通信走到launcher的ApplicationThread的scheduleTransaction函数。
2.3 launcher处理pasue
在launcher进程内,从binder线程切换到主线程,然后调用TransactionExecutor.java的execute,最后走到executeLifecycleState:
java
// TransactionExecutor.java
private void executeLifecycleState(ClientTransaction transaction) {
...
// Execute the final transition with proper parameters.
// 1
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
// 2
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
- 走到
PauseActivityItem.java的execute,调用ActivityThread.java的performPauseActivity,然后走到Activity.java的performPause, 这里会走到我们熟悉的Actvity的onPause,并输出evnet log:wm_on_paused_called - 走到
PauseActivityItem.java的postExecute,其中会走到ActivityClient.java的getActivityClientController().activityPaused(token);,getActivityClientController()会返回ActivityClientControllerSingleton类的静态对象,看下它的实现:
java
// ActivityClient.java
private static class ActivityClientControllerSingleton
extends Singleton<IActivityClientController> {
...
protected IActivityClientController create() {
try {
return ActivityTaskManager.getService().getActivityClientController();
...
}
mark 1可以看出来getActivityClientController()其实就是为了方便和ATMS通信,返回了ATMS的内部类ActivityClientController,它当然也是继承自
IInterface.stub的:class ActivityClientController extends IActivityClientController.Stub,
回到上面的postExecute,它其实最后就会和system_server通信,走到ActivityClientController.java的activityPaused.
2.4 launcher通知system servfer Paused
java
// ActivityClientController.java
public void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "activityPaused");
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
if (r != null) {
r.activityPaused(false);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
Binder.restoreCallingIdentity(origId);
}
通过token定位到具体的ActivityRecord,调用ActivityRecord的activityPaused:
java
// ActivityRecord.java
void activityPaused(boolean timeout) {
ProtoLog.v(WM_DEBUG_STATES, "Activity paused: token=%s, timeout=%b", appToken,
timeout);
// 1
final TaskFragment taskFragment = getTaskFragment();
if (taskFragment != null) {
removePauseTimeout();
// 2
final ActivityRecord pausingActivity = taskFragment.getPausingActivity();
if (pausingActivity == this) {
ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s %s", this,
(timeout ? "(due to timeout)" : " (pause complete)"));
mAtmService.deferWindowLayout();
try {
// 3
taskFragment.completePause(true /* resumeNext */, null /* resumingActivity */);
} finally {
mAtmService.continueWindowLayout();
}
return;
} else {
- 找到ActivityRecord对应的Task,也就是launcher对应的Home Task.
- 返回Task的
mPausingActivity,在上面system server pause launcher的过程中就给mPausingActivity赋值了,所以if可以走进去。 - 走到
TaskFragment.java的completePause.
3 创建app process
3.1 分析startProcessAsync调用栈
app resume的处理时序又是什么样的,如果只是正向分析代码很难,会发现很多case都会走到startProcessAsync。
不妨通过关键节点来打印堆栈来看下,log有点多,分段解读。
3.1.1 第一段log
java
Test111 : DefaultTaskDisplayArea@253126244 add child 222 Task{936fd9 #22 type=standard ?? U=0 visible=false visibleRequested=false mode=undefined translucent=true sz=0}
// ...省略startActivity Task的创建和挂载log
Test111 : Task{936fd9 #22 type=standard A=10106:com.example.mytestapplication U=0 visible=false visibleRequested=false mode=fullscreen translucent=true sz=0} add child 222 ActivityRecord{1c23095 u0 com.example.mytestapplication/.MainActivity
// ...省略startActivity ActivityRecord 的创建和挂载log
startActivity过程中创建Task和ActivityRecord, 并挂载到窗口层级树。
3.1.2 第二段log
java
Test111 : startProcessAsync, processName=com.example.mytestapplication
Test111 : java.lang.Exception
Test111 : at com.android.server.wm.ActivityTaskManagerService.startProcessAsync(ActivityTaskManagerService.java:4681)
Test111 : at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1081)
Test111 : at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5035)
Test111 : at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4970)
Test111 : at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2361)
Test111 : at com.android.server.wm.ActivityStarter.startActivityInner(ActivityStarter.java:1842)
Test111 : at com.android.server.wm.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1584)
Test111 : at com.android.server.wm.ActivityStarter.executeRequest(ActivityStarter.java:1185)
Test111 : at com.android.server.wm.ActivityStarter.execute(ActivityStarter.java:672)
Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1243)
Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivityAsUser(ActivityTaskManagerService.java:1215)
Test111 : at com.android.server.wm.ActivityTaskManagerService.startActivity(ActivityTaskManagerService.java:1190)
Test111 : at android.app.IActivityTaskManager$Stub.onTransact(IActivityTaskManager.java:893)
Test111 : at com.android.server.wm.ActivityTaskManagerService.onTransact(ActivityTaskManagerService.java:5124)
Test111 : at android.os.Binder.execTransactInternal(Binder.java:1179)
Test111 : at android.os.Binder.execTransact(Binder.java:1143)
Test111 : startProcessLocked, processName=com.example.mytestapplication
Test111 : startProcess222, processName=com.example.mytestapplication
Test111 : java.lang.Exception
Test111 : at com.android.server.am.ProcessList.startProcess(ProcessList.java:2432)
Test111 : at com.android.server.am.ProcessList.handleProcessStart(ProcessList.java:2177)
Test111 : at com.android.server.am.ProcessList.lambda$startProcessLocked$0$ProcessList(ProcessList.java:2104)
Test111 : at com.android.server.am.ProcessList$$ExternalSyntheticLambda1.run(Unknown Source:22)
Test111 : at android.os.Handler.handleCallback(Handler.java:938)
Test111 : at android.os.Handler.dispatchMessage(Handler.java:99)
Test111 : at android.os.Looper.loopOnce(Looper.java:201)
Test111 : at android.os.Looper.loop(Looper.java:288)
Test111 : at android.os.HandlerThread.run(HandlerThread.java:67)
Test111 : at com.android.server.ServiceThread.run(ServiceThread.java:44)
这一段log,我分别在ActivityTaskManagerService.java -- startProcessAsync函数,ProcessList.java -- startProcessLocked函数,以及ProcessList.java -- startProcess函数 ,追加log堆栈调用打印。
可以看到start app进程的地方还是在ActivityStarter.startActivityInner:
java
// ActivityStarter.java
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, boolean restrictedBgActivity,
NeededUriGrants intentGrants) {
...
if (mTargetRootTask == null) {
// 1 创建Task并挂载到窗口层级树
mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
if (newTask) {
// 2 创建ActivityRecord并挂载到窗口层级树
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
addOrReparentStartingActivity(targetTask, "adding to task");
}
...
// 3
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
mark 3中经过一系列的调用,在TaskFragment.java -- resumeTopActivity函数中:
java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canResumeByCompat()) {
return false;Resume
}
...
// 1
boolean pausing = !deferPause && taskDisplayArea.pauseBackTasks(next);
// 2
if (pausing) {
...
// 3
if (next.attachedToProcess()) {
next.app.updateProcessInfo(false /* updateServiceConnectionActivities */,
true /* activityChange */, false /* updateOomAdj */,
false /* addPendingTopUid */);
// 4
} else if (!next.isProcessRunning()) {
// Since the start-process is asynchronous, if we already know the process of next
// activity isn't running, we can start the process earlier to save the time to wait
// for the current activity to be paused.
final boolean isTop = this == taskDisplayArea.getFocusedRootTask();
// 5
mAtmService.startProcessAsync(next, false /* knownToBeDead */, isTop,
isTop ? "pre-top-activity" : "pre-activity");
}
- pause流程,上面说了。
- 上面刚处理pause,所以在pausing中。
- 我们是冷启动app,app进程还没有创建出来,所以这里if不满足
- 我们是冷启动app,app进程还没有创建出来,if满足
- 开始startProcess流程,先调用ATMS的
startProcessAsync,再调用AMS的startProcess,最后走到Process.java的start函数来拉起app进程。
令我比较疑惑的是,除了在startActivityInner中会走startProcess, 还有其他地方也会走到startProcess, 比如如下:
3.1.3 第三段log
java
Test111 : startProcessAsync, processName=com.example.mytestapplication
Test111 : java.lang.Exception
Test111 : at com.android.server.wm.ActivityTaskManagerService.startProcessAsync(ActivityTaskManagerService.java:4681)
Test111 : at com.android.server.wm.ActivityTaskSupervisor.startSpecificActivity(ActivityTaskSupervisor.java:1013)
Test111 : at com.android.server.wm.TaskFragment.resumeTopActivity(TaskFragment.java:1345)
Test111 : at com.android.server.wm.Task.resumeTopActivityInnerLocked(Task.java:5035)
Test111 : at com.android.server.wm.Task.resumeTopActivityUncheckedLocked(Task.java:4970)
Test111 : at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2361)
Test111 : at com.android.server.wm.RootWindowContainer.resumeFocusedTasksTopActivities(RootWindowContainer.java:2347)
Test111 : at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1596)
Test111 : at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:5714)
Test111 : at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:175)
Test111 : at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:548)
Test111 : at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:121)
Test111 : at android.os.Binder.execTransactInternal(Binder.java:1179)
Test111 : at android.os.Binder.execTransact(Binder.java:1143)
在lanuncer进程回调activityPaused的completePause处理中,也会走到startProcessAsync
3.1.4 第四段log
java
Test111 : startProcessAsync, processName=com.example.mytestapplication
Test111 : java.lang.Exception
Test111 : at com.android.server.wm.ActivityTaskManagerService.startProcessAsync(ActivityTaskManagerService.java:4681)
Test111 : at com.android.server.wm.ActivityTaskSupervisor.startSpecificActivity(ActivityTaskSupervisor.java:1013)
Test111 : at com.android.server.wm.EnsureActivitiesVisibleHelper.makeVisibleAndRestartIfNeeded(EnsureActivitiesVisibleHelper.java:265)
Test111 : at com.android.server.wm.EnsureActivitiesVisibleHelper.setActivityVisibilityState(EnsureActivitiesVisibleHelper.java:191)
Test111 : at com.android.server.wm.EnsureActivitiesVisibleHelper.process(EnsureActivitiesVisibleHelper.java:139)
Test111 : at com.android.server.wm.TaskFragment.updateActivityVisibilities(TaskFragment.java:979)
Test111 : at com.android.server.wm.Task.lambda$ensureActivitiesVisible$15(Task.java:4866)
Test111 : at com.android.server.wm.Task$$ExternalSyntheticLambda20.accept(Unknown Source:10)
Test111 : at com.android.server.wm.Task.forAllLeafTasks(Task.java:3185)
Test111 : at com.android.server.wm.Task.ensureActivitiesVisible(Task.java:4865)
Test111 : at com.android.server.wm.DisplayContent.lambda$ensureActivitiesVisible$46(DisplayContent.java:5999)
Test111 : at com.android.server.wm.DisplayContent$$ExternalSyntheticLambda17.accept(Unknown Source:10)
Test111 : at com.android.server.wm.Task.forAllRootTasks(Task.java:3197)
Test111 : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
Test111 : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
Test111 : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
Test111 : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
Test111 : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
Test111 : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1817)
Test111 : at com.android.server.wm.WindowContainer.forAllRootTasks(WindowContainer.java:1810)
Test111 : at com.android.server.wm.DisplayContent.ensureActivitiesVisible(DisplayContent.java:5998)
Test111 : at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:2020)
Test111 : at com.android.server.wm.RootWindowContainer.ensureActivitiesVisible(RootWindowContainer.java:2001)
Test111 : at com.android.server.wm.TaskFragment.completePause(TaskFragment.java:1616)
Test111 : at com.android.server.wm.ActivityRecord.activityPaused(ActivityRecord.java:5714)
Test111 : at com.android.server.wm.ActivityClientController.activityPaused(ActivityClientController.java:175)
Test111 : at android.app.IActivityClientController$Stub.onTransact(IActivityClientController.java:548)
Test111 : at com.android.server.wm.ActivityClientController.onTransact(ActivityClientController.java:121)
Test111 : at android.os.Binder.execTransactInternal(Binder.java:1179)
Test111 : at android.os.Binder.execTransact(Binder.java:1143)
在lanuncer进程回调activityPaused的ensureActivitiesVisible处理中,也会走到startProcessAsync
但前面已经有startProcess的触发了,后面又来了2次,会不会有问题,答案当然是不会。
如果app进程拉起的快,会在ProcessList.java的startProcessLocked函数中判断如果该app进程已经启动,直接return.
如果app进程拉起的慢,同样会在ProcessList.java的startProcessLocked函数(和上面不是同一个startProcessLocked)中判断该app进程是isPendingStart,也会return。
3.2 app进程启动
上面讲了AMS通过zygote拉起app进程。那么app进程起来后的流程是什么样的,继续分析。
当app进程起来后,会先执行ActivityThread.java的main函数。
java
// ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
...
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
构造出ActivityThread,并调用其attach函数,在ActivityThread的attach函数中,调用mgr.attachApplication(mAppThread, startSeq);, mgr就是AMS在app侧的代理。所以这里就调用到了system server进程中,调用ActivityManagerService.java的attachApplication.
java
// ActivityManagerService.java
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
// 1
EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
...
// 2
thread.bindApplication( ...
// 3
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
...
- 输出event log:
am_proc_bound: [0,1854,com.example.mytestapplication] - 回调ActivityThread的bindApplication,在app进程中,在这一步会调用
Application的onCreate - 调用ATMS的attachApplication, ATMS内部又会调用
RootWindowContainer.java的attachApplication.
java
boolean attachApplication(WindowProcessController app) throws RemoteException {
...
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx) {
...
final DisplayContent display = getChildAt(displayNdx);
//1
display.forAllRootTasks(rootTask -> {
if (mTmpRemoteException != null) {
return;
}
if (rootTask.getVisibility(null /* starting */)
== TASK_FRAGMENT_VISIBILITY_INVISIBLE) {
return;
}
final PooledFunction c = PooledLambda.obtainFunction(
RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
PooledLambda.__(ActivityRecord.class), app,
rootTask.topRunningActivity());
// 2
rootTask.forAllActivities(c);
c.recycle();
});
...
}
forAllRootTasks: 轮询窗口层级结构树,它的真正实现在Task.java中:
java
@Override
void forAllRootTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
if (isRootTask()) {
callback.accept(this);
}
}
callback.accept(this); : 将Task作为参数传入attachApplication函数内的lambda表达式, 并执行。
- lambda表达式内又会轮询窗口层级结构树,它的实现在ActivityRecord.java中:
java
boolean forAllActivities(
Function<ActivityRecord, Boolean> callback, boolean traverseTopToBottom) {
return callback.apply(this);
}
将ActivityRecord作为参数带入上面的PooledFunction c,并执行c, c的实现是调用RootWindowContainer::startActivityForAttachedApplicationIfNeeded,其中又会调用ActivityTaskSupervisor.java的
realStartActivityLocked。
4 app process onCreate/onStart/onResume
4.1 realStartActivityLocked
java
// ActivityTaskSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// 1
if (!mRootWindowContainer.allPausedActivitiesComplete()) {
// While there are activities pausing we skipping starting any new activities until
// pauses are complete. NOTE: that we also do this for activities that are starting in
// the paused state because they will first be resumed then paused on the client side.
ProtoLog.v(WM_DEBUG_STATES,
"realStartActivityLocked: Skipping start of r=%s some activities pausing...",
r);
return false;
...
// 2
EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
task.mTaskId, r.shortComponentName);
// 3
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
...
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
// 4
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
// 5
rootTask.minimalResumeActivityLocked(r);
- 检查是不是所有的activity是否已经pause,如果没有是不允许继续往下走的.
- 输出event log:
wm_restart_activity: [0,29503637,22,com.example.mytestapplication/.MainActivity],注意这里面的restart不是重新开始的意思,而是real start的缩写。 - 构造一个
LaunchActivityItem对象,添加到clientTransaction的mActivityCallbacks, 构造一个ResumeActivityItem对象,赋值给clientTransaction的mLifecycleStateRequest成员。 scheduleTransaction, 内部是一次binder通信,调用到app进程,走到ActivityThread.java内部类ApplicationThread的scheduleTransaction函数,在走到TransactionExecutor.java的execute函数,参考下面4.2- minimalResumeActivityLocked,参考下面4.3
4.2 scheduleTransaction
java
// TransactionExecutor.java
public void execute(ClientTransaction transaction) {
...
// 1
executeCallbacks(transaction);
// 2
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
-
从
clientTransaction的mActivityCallbacks中拿到LaunchActivityItem对象,执行其Execute函数,最终会走到Activity.java的performCreate, 在这里会回调Activity的onCreate,以及输出event log:wm_on_create_called: [29503637,com.example.mytestapplication.MainActivity,performCreate] -
executeLifecycleState中有2个重要的处理, 参考下面代码中的注释:
java
// TransactionExecutor.java
private void executeLifecycleState(ClientTransaction transaction) {
// 1
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
...
// Cycle to the state right before the final requested state.
// 2
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// Execute the final transition with proper parameters.
// 3
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
-
拿到ResumeActivityItem对象。
-
因为当前是onCreate状态,要迁移到onResume状态,中间还间隔了一个onStart,所以这里会走一次ActivityThread.java的handleStartActivity,最后走到
Activity.java的performStart函数,java// Activity.java final void performStart(String reason) { ... // 回调Activity OnStart mInstrumentation.callActivityOnStart(this); ... // 输出event log: wm_on_start_called: [268082872,com.example.mytestapplication.MainActivity,handleStartActivity] EventLogTags.writeWmOnStartCalled(mIdent, getComponentName().getClassName(), reason); -
执行ResumeActivityItem的execute,会执行到
Activity.java的performResume函数,其中会回调Activity的OnResume,并且输出event log:wm_on_resume_called: [268082872,com.example.mytestapplication.MainActivity,RESUME_ACTIVITY]