SwallowJoe的博客

Be a real go-getter,
NEVER SETTLE!

0%

WMS(3)-ActivityRecord和WindowToken.md

以下分析基于Android S.

简述

上文中我们知道Activity的Window被添加至WMS其实就是该Activity的ViewRootImpl中的W作为IWindow、存储该Activity窗口属性信息的LayoutParams以及InputChannel被传入WMS,然后生成WindowToken, 当然之后WindowToken自然是保存在DisplayContent.mTokenMap中,该map的key即对应Activity中的mToken(LocalActivityRecord)。

在Activity的Window被添加至WMS中,我们仅仅分析了一半,然后重点区分析了DisplayContent的构建,了解了其层次结构器的创建过程以及layer的个数和Window类型对应的layer。现在我们接着看WindowToken的创建,上文中留有一个疑问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DisplayArea.Tokens findAreaForToken(int windowType, boolean ownerCanManageAppTokens,
boolean roundedCornerOverlay) {
// 获取window类型对应的layer,getWindowLayerFromTypeLw看[Window类型转Layer](#222-windowmanagerpolicygetwindowlayerfromtypelw)。
// 一般应用的window类型是 TYPE_BASE_APPLICATION (值为1,handleResumeActivity中赋值的)
// 所以windowLayerFromType就是APPLICATION_LAYER!
int windowLayerFromType = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
ownerCanManageAppTokens, roundedCornerOverlay);
// 所以这里就会抛出异常???
if (windowLayerFromType == APPLICATION_LAYER) {
throw new IllegalArgumentException(
"There shouldn't be WindowToken on APPLICATION_LAYER");
}
return mAreaForLayer[windowLayerFromType];
}

因为Activity对应的windowType是TYPE_BASE_APPLICATION,所以拿到的windowLayerFromType就是APPLICATION_LAYER,那么这里必然会抛出异常!

当然按照正常理解来说,必然不会发生异常才对,所以是我们流程分析哪里有问题? 是也不是,这里就要留意到应用启动过程了,回到Activity的启动过程,我们先看ActivityRecord的创建过程。

一. ActivityRecord的创建

ActivityRecord类是WindowToken子类:

3-1

而且从名字中也可以看出,这个类应该是和Activity一一对应的,那么应该在Activity启动流程中哪个步骤创建其对象呢?不难理解,肯定是在startActivity的过程中。

Activity的启动流程这里就不展开了,直接看关键代码.

1.1 ActivityTaskManagerService.startActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
......
// obtainStarter其实就是通过ActivityStarter.DefaultFactory获取ActivityStarter
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setUserId(userId)
.execute(); // 执行Activity的启动
}

将Activity的启动委托给ActivityStarter执行。

1.2 ActivityStarter.execute

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
int execute() {
try {
......
synchronized (mService.mGlobalLock) {
......
res = executeRequest(mRequest);
......
}

private int executeRequest(Request request) {
......
// 注意这里的inTask是null的,因为ActivityStarter构建时没有设置inTask.
Task inTask = request.inTask;
......
// [1.2.1] 针对此次启动的Activity创建对应的ActivityRecord
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
......
// [1.3] 启动Activity
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
restrictedBgActivity, intentGrants);
......
}

ActivityRecord的初始化是采用了Build模式.

1.2.1 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
private ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage,
@Nullable String _launchedFromFeature, Intent _intent, String _resolvedType,
ActivityInfo aInfo, Configuration _configuration, ActivityRecord _resultTo,
String _resultWho, int _reqCode, boolean _componentSpecified,
boolean _rootVoiceInteraction, ActivityTaskSupervisor supervisor,
ActivityOptions options, ActivityRecord sourceRecord, PersistableBundle persistentState,
TaskDescription _taskDescription, long _createTime) {

// 这里创建的Token是IApplicationToken.Stub的子类, 保存在ActivityRecord父类WindowToken的成员变量token中
super(_service.mWindowManager, new Token(_intent).asBinder(), TYPE_APPLICATION, true,
null /* displayContent */, false /* ownerCanManageAppTokens */);

mAtmService = _service;
appToken = (Token) token;
info = aInfo;
......
appToken.attach(this);
......
}

static class Token extends IApplicationToken.Stub {
......
private void attach(ActivityRecord activity) {
if (weakActivity != null) {
throw new IllegalStateException("Already attached..." + this);
}
// 将传入的ActivityRecord用弱引用方式保存起来
weakActivity = new WeakReference<>(activity);
}
......

所以ActivityRecord里的appToken其实是ActivityRecord初始化时创建的Token(为IApplicationToken.Stub的子类),里面保存了该Activity的Intent信息。

1.3 ActivityStarter.startActivityUnchecked

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
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
......
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
......
}

int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
boolean restrictedBgActivity, NeededUriGrants intentGrants) {
// 1.3.1 设置初始化状态
setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
voiceInteractor, restrictedBgActivity);
......
// 获取可重用的task
final Task reusedTask = getReusableTask();
......
// 计算目标task
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
final boolean newTask = targetTask == null;
mTargetTask = targetTask;
......
// 因为当前Activity是应用启动的第一个Activity,所以newTask为true,targetTaskTop就是null的了
final ActivityRecord targetTaskTop = newTask
? null : targetTask.getTopNonFinishingActivity();
if (targetTaskTop != null) {
// 为此次Activity的启动回收task
startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
} else {
mAddingToTask = true;
}
......
// 获取当前焦点(前台)Task
final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
if (topRootTask != null) {
// 判断待启动的Activity是否与前台Activity一致
startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
}
if (mTargetRootTask == null) {
// 获取root task.
mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
}
// 需要创建新的task
if (newTask) {
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
// 设置新的Task
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
addOrReparentStartingActivity(targetTask, "adding to task");
}
......
// 交给对应Task启动Activity
mTargetRootTask.startActivityLocked(mStartActivity,
topRootTask != null ? topRootTask.getTopNonFinishingActivity() : null, newTask,
mKeepCurTransition, mOptions, startFromSamePackage);
......
}

private void setNewTask(Task taskToAffiliate) {
final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
// 创建新的Task,关于Task的创建我们后续分析
final Task task = mTargetRootTask.reuseOrCreateTask(
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
mService.getTransitionController().collectExistenceChange(task);
// [1.4] 保存Activity至task!
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");

......
}

这里我们假设启动的Activity是应用的首个Activity,而且也没有设置affinity,这样在启动该Activity时,会创建新的Task, 并在该Task中保存ActivityRecord!

1.3.1 ActivityStarter.setInitialState - 设置初始化状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void setInitialState(ActivityRecord r, ActivityOptions options, Task inTask,
boolean doResume, int startFlags, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
boolean restrictedBgActivity) {
reset(false /* clearRequest */);

mStartActivity = r;
......
mLaunchParams.reset();
......
// 因为mLaunchParams被重置了,所以mPreferredTaskDisplayArea获取的就是mRootWindowContainer.getDefaultTaskDisplayArea
// 即上文中RootDisplayArea创建的Result中的mDefaultTaskDisplayArea
mPreferredTaskDisplayArea = mLaunchParams.hasPreferredTaskDisplayArea()
? mLaunchParams.mPreferredTaskDisplayArea
: mRootWindowContainer.getDefaultTaskDisplayArea();
}

这里首先先清理ActivityStarter内部成员,然后依次赋值。

1.4 ActivityStarter.addOrReparentStartingActivity

1
2
3
4
5
6
7
8
9
10
private void addOrReparentStartingActivity(Task parent, String reason) {
// mStartActivity是该Activity启动时创建的ActivityRecord.
// ActivityRecord.getTask就是获取其task成员,该成员目前是没有被赋值的
if (mStartActivity.getTask() == null || mStartActivity.getTask() == parent) {
// [1.5] 将该ActivityRecord添加至task中
parent.addChild(mStartActivity);
} else {
mStartActivity.reparent(parent, parent.getChildCount() /* top */, reason);
}
}

1.5 Task.addChild

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void addChild(ActivityRecord r) {
// 默认添加到该Task的最上层
addChild(r, Integer.MAX_VALUE /* add on top */);
}

@Override
void addChild(WindowContainer child, int index) {
// 判断mChildren集合中是否存在元素
boolean hadChild = hasChild();
// [1.5.1] 获取当前Task最上层的WindowContainer对应的Activity类型
final int activityType = getActivityType();
// [1.5.2] 调整被添加的ActivityRecord在task中的位置
index = getAdjustedChildPosition(child, index);
// [1.6] 将WindowContainer添加至mChildren中index位置
super.addChild(child, index);
......
}

1.5.1 Task.getActivityType

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
public int getActivityType() {
// Task的父类是WindowContainer, WindowContainer的父类是ConfigurationContainer
final int applicationType = super.getActivityType();
if (applicationType != ACTIVITY_TYPE_UNDEFINED || !hasChild()) {
return applicationType;
}
return getTopChild().getActivityType();
}

// frameworks/base/core/java/android/content/res/Configuration.java
public int getActivityType() {
// mFullConfiguration就是Configuration.java类
return mFullConfiguration.windowConfiguration.getActivityType();
}

// frameworks/base/core/java/android/app/WindowConfiguration.java
@ActivityType
public int getActivityType() {
return mActivityType;
}

ActivityType有如下取值:

名称 含义
ACTIVITY_TYPE_UNDEFINED 0 Activity类型尚未定义
ACTIVITY_TYPE_STANDARD 1 标准Activity类型
ACTIVITY_TYPE_HOME 2 Home或Launcher的Activity类型
ACTIVITY_TYPE_RECENTS 3 Recents或者Overview的Activity类型,系统中只有一个具有此类型的Activity
ACTIVITY_TYPE_ASSISTANT 4 Assistant Activity类型
ACTIVITY_TYPE_DREAM 5 Dream Activity类型

一般情况都是ACTIVITY_TYPE_STANDARD或者ACTIVITY_TYPE_HOME类型。当前Task获取的值应该是初始化的默认值:

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
// ConfigurationContainer.java:mFullConfiguration
private Configuration mFullConfiguration = new Configuration();

// Configuration.java:windowConfiguration
public final WindowConfiguration windowConfiguration = new WindowConfiguration();

// WindowConfiguration.java
public WindowConfiguration() {
unset();
}

public void unset() {
setToDefaults();
}

/** @hide */
public void setToDefaults() {
setAppBounds(null);
setBounds(null);
setMaxBounds(null);
setWindowingMode(WINDOWING_MODE_UNDEFINED);
setActivityType(ACTIVITY_TYPE_UNDEFINED);
setAlwaysOnTop(ALWAYS_ON_TOP_UNDEFINED);
setRotation(ROTATION_UNDEFINED);
setDisplayWindowingMode(WINDOWING_MODE_UNDEFINED);
}

可以看到,ActivityType是被设置成:ACTIVITY_TYPE_UNDEFINED,也即未定义类型!

1.5.2 Task.getAdjustedChildPosition

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
private int getAdjustedChildPosition(WindowContainer wc, int suggestedPosition) {
// wc就是创建的ActivityRecord, 这里就是检查Activity是否带有FLAG_SHOW_FOR_ALL_USERS标志
// 或者该Activity所属的userId是否是当前userId,即非当前用户的Activity不可见
final boolean canShowChild = wc.showToCurrentUser();

final int size = mChildren.size();

// 根据WindowContainer是否可见,决定该WC应该被插入Task的位置
int minPosition = (canShowChild) ? computeMinUserPosition(0, size) : 0;
int maxPosition = (canShowChild) ? size : computeMaxUserPosition(size - 1);

// [1.5.2.1] 检查该WindowContainer是否是永远处于Task最上层
if (!wc.isAlwaysOnTop()) {

// 将所有应该永远处于最上层的WC放在Task的最上层
while (maxPosition > minPosition) {
if (!mChildren.get(maxPosition - 1).isAlwaysOnTop()) break;
--maxPosition;
}
}

// 当该WC可以处于POSITION_BOTTOM且minPosition也是0时,返回POSITION_BOTTOM
// 或者可以处于POSITION_TOP且maxPosition超过目前children数量时,返回POSITION_TOP
if (suggestedPosition == POSITION_BOTTOM && minPosition == 0) {
return POSITION_BOTTOM;
} else if (suggestedPosition == POSITION_TOP && maxPosition >= (size - 1)) {
return POSITION_TOP;
}
// 挑选一个合适的位置
return Math.min(Math.max(suggestedPosition, minPosition), maxPosition);
}

这里是通过检查WindowContainer是否可见的属性以及是否应该永远处于最上层来调整该WC应该被插入Task的哪个位置。

当我们ActivityRecord被添加入一个新建的Task时,毫无疑问应该是处于最上层即返回POSITION_TOP。

1.5.2.1 WindowContainer.isAlwaysOnTop

1
2
3
4
5
6
7
public boolean isAlwaysOnTop() {
if (mWindowingMode == WINDOWING_MODE_PINNED) return true;
if (mActivityType == ACTIVITY_TYPE_DREAM) return true;
if (mAlwaysOnTop != ALWAYS_ON_TOP_ON) return false;
return mWindowingMode == WINDOWING_MODE_FREEFORM
|| mWindowingMode == WINDOWING_MODE_MULTI_WINDOW;
}

说明如下情况,该WindowContainer应该始终处于所在Task的最上层:

  1. window模式为WINDOWING_MODE_PINNED
  2. Activity类型是ACTIVITY_TYPE_DREAM
  3. 当mAlwaysOnTop为ALWAYS_ON_TOP_ON,window模式为WINDOWING_MODE_FREEFORM或WINDOWING_MODE_MULTI_WINDOW

1.6 WindowContainer.addChild

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@CallSuper
void addChild(E child, int index) {
......
// 最后调整index
if (index == POSITION_TOP) {
index = mChildren.size();
} else if (index == POSITION_BOTTOM) {
index = 0;
}

// 将child保存在mChildren中的特定位置
mChildren.add(index, child);

// [1.7] 让child保存该WC(即Task)
child.setParent(this);
}

@CallSuper: 是Android中特有的注解,如果子类覆盖了同名方法而没有显示调用父类的该方法时就会报错!

这个也挺简单的,首先最后调整一下index:

  1. 如果传入的index为POSITION_TOP,则将index设置为当前mChildren的size值,意为将待存入的child保存在mChildren中最后一位(上面)
  2. 如果传入的index为POSITION_BOTTOM, 则将index设置为0,意为将待存入的child保存在mChildren中第一位(下面)

然后让child(ActivityRecord)保存该WC(即Task)。

1.7 WindowContainer.setParent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
final protected void setParent(WindowContainer<WindowContainer> parent) {
final WindowContainer oldParent = mParent;
mParent = parent;

if (mParent != null) {
mParent.onChildAdded(this);
}
// ActivityRecord创建时,该值默认为false,只有被调用reparent重设父集时才会被短暂更改为true
if (!mReparenting) {
onSyncReparent(oldParent, mParent);
// mDisplayContent此时还是null的,而Task.mDisplayContent就是defaultDisplayContent
if (mParent != null && mParent.mDisplayContent != null
&& mDisplayContent != mParent.mDisplayContent) {
// [1.8] 更改当前WC(ActivityRecord)的DisplayContent
onDisplayChanged(mParent.mDisplayContent);
}
// [1.7.1] 当前ActivityRecord的parent有更改
onParentChanged(mParent, oldParent);
}
}

设置WC(ActivityRecord)的父集(mParent, 即保存该WC的Task), 如有必要同步Task中DisplayContent至该WC中。

1.7.1 ActivityRecord.onParentChanged

1
2
3
4
5
6
7
8
@Override
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
final Task oldTask = oldParent != null ? (Task) oldParent : null;
final Task newTask = newParent != null ? (Task) newParent : null;
// 存入ActivityRecord.task中
this.task = newTask;
......
}

将传入的ConfigurationContainer作为Task,存入ActivityRecord.task中,其余部分暂时先不研究。

1.8 ActivityRecord.onDisplayChanged

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
@Override
void onDisplayChanged(DisplayContent dc) {
DisplayContent prevDc = mDisplayContent;
// WindowToken.onDisplayChanged
super.onDisplayChanged(dc);
......
}

// WindowToken.java:onDisplayChanged
@Override
void onDisplayChanged(DisplayContent dc) {
// [1.9] 将WindowToken(ActivityRecord)保存至DisplayContent中
dc.reParentWindowToken(this);

// WindowContainer.onDisplayChanged
super.onDisplayChanged(dc);
}

// WindowContainer.java:onDisplayChanged
void onDisplayChanged(DisplayContent dc) {
if (mDisplayContent != null && mDisplayContent.mChangingContainers.remove(this)) {
// Cancel any change transition queued-up for this container on the old display.
mSurfaceFreezer.unfreeze(getPendingTransaction());
}
mDisplayContent = dc;
if (dc != null && dc != this) {
dc.getPendingTransaction().merge(mPendingTransaction);
}
// 将mChildren中的每个WC的DisplayContent也同步更改
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowContainer child = mChildren.get(i);
child.onDisplayChanged(dc);
}
for (int i = mListeners.size() - 1; i >= 0; --i) {
mListeners.get(i).onDisplayChanged(dc);
}
}

这里最主要的是理清ActivityRecord、WindowToken、Task和WindowContainer之间的继承关系:

3-2

1.9 DisplayContent.reParentWindowToken

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void reParentWindowToken(WindowToken token) {
// prevDc目前还是null的
final DisplayContent prevDc = token.getDisplayContent();
if (prevDc == this) {
return;
}
if (prevDc != null) {
......
}

// 将ActivityRecord添加到该DC中,key为WindowToken的.token值
addWindowToken(token.token, token);
......
}

由于此时还处于ActivityRecord刚被创建,正在第一次被设置DisplayContent时,所以其DisplayContent此时还是null的。那么就直接将该WindowToken(即ActivityRecord)保存在此DisplayContent中,注意token.token其实是WindowToken.token, 这个值我们之前分析过,是attrs.token,也就是从App进程传入的LocalActivityRecord.

1.10 DisplayContent.addWindowToken

1
2
3
4
5
6
7
8
9
10
void addWindowToken(IBinder binder, WindowToken token) {
final DisplayContent dc = mWmService.mRoot.getWindowTokenDisplay(token);
......
// 将ActivityRecord保存在DisplayContent中,key为WindowToken的token变量,即app传入的LayoutParam中的token
mTokenMap.put(binder, token);
// WindowToken(其实是ActivityRecord)的asActivityRecord函数返回值不为null
if (token.asActivityRecord() == null) {
......
}
}

好了,我们终于明白了一个ActivityRecord是如何被添加进DisplayContent中了,看到这里是不是似曾相识呢?Bingo, 之前我们的windowToken创建时会抛出一个异常,就是因为这个WindowToken.asActivityRecord返回值为null, 导致DisplayContent中添加该WindowToken时找不到合适layer!

1
2
3
4
5
6
7
int windowLayerFromType = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
ownerCanManageAppTokens, roundedCornerOverlay);
// 所以这里就会抛出异常???
if (windowLayerFromType == APPLICATION_LAYER) {
throw new IllegalArgumentException(
"There shouldn't be WindowToken on APPLICATION_LAYER");
}

现在我们知道了,在app的Activity被resume时,早就已经有了其WindowToken(ActivityRecord)被保存在DisplayContent的mTokenMap中。所以回过头我们看WMS.addWindow方法:

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
public int addWindow(Session session, IWindow client, LayoutParams attrs, int viewVisibility,
int displayId, int requestUserId, InsetsState requestedVisibility,
InputChannel outInputChannel, InsetsState outInsetsState,
InsetsSourceControl[] outActiveControls) {
......
// 窗口类型保存在LayoutParams中
final int type = attrs.type;
synchronized (mGlobalLock) {
......
// 这里DisplayContent中至少包含该App的一个WindowToke,也就是Activity被start时创建的ActivityRecord!
WindowToken token = displayContent.getWindowToken(
hasParent ? parentWindow.mAttrs.token : attrs.token);
......
// 所以这里就不会进入了,疑问解除!
if (token == null) {
.....
}
...
// 初始化WindowState
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], attrs, viewVisibility, session.mUid, userId,
session.mCanAddInternalSystemWindow);
......
// 创建SurfaceSession, 用来和SurfaceFlinger通信
win.attach();
// 保存WindowState
mWindowMap.put(client.asBinder(), win);
......
win.mToken.addWindow(win);
......
......
}

啊哈,异常解除,因为Activity需要resume必须先start, 而start过程中就会创建其对应ActivityRecord并保存在对应DisplayContent的mTokenMap中!

最后附上一张时序图以备忘:

3-3

接下来,我们继续看WMS.addWindow的流程:WindowState的创建及其管理。

欢迎关注我的其它发布渠道