窗口容器层级结构
类
// 最末端的节点是 WindowState
class WindowState extends WindowContainer<WindowState>
// 其次是 WindowToken 和其子类
class WindowToken extends WindowContainer<WindowState>
class ActivityRecord extends WindowToken
class WallpaperWindowToken extends WindowToken
// 中间是 Task, Activity堆栈
class Task extends TaskFragment(class TaskFragment extends WindowContainer<WindowContainer>)
// 再次是 DisplayArea
class TaskDisplayArea extends DisplayArea<WindowContainer>
class DisplayArea.Tokens extends DisplayArea<WindowToken>
class DisplayContent.ImeContainer extends DisplayArea.Tokens
// 再次是 DisplayContent, 表示一个屏幕
class DisplayContent extends RootDisplayArea(extends DisplayArea(<T extends WindowContainer> extends WindowContainer))
// 最后是 RootWindowContainer
class RootWindowContainer extends WindowContainer<DisplayContent>
窗口基类 WindowContainer
所有容器都继承自 WindowContainer。下面介绍 WIndowContainer 的重要成员和方法:
层级关系:
- mParent 表示父级窗口;
- mChildren 表示子窗口列表;列表按子节点在屏幕显示的z轴顺序排列, 最上面的窗口容器在列表尾部
- addChild(), setParent(), 增加子窗口、设置父窗口;
- positionChildAt(), reparent(),改变子窗口的位置,重新设置父窗口;
- mTreeWeight 在树状结构中的权重,包括所有子窗口和当前窗口;
Surface 和动画:
- mSurfaceControl 每个窗口的 Surface
- mSurfaceAnimator 执行动画
Z轴:
- setLayer(), assignLayer() 设置当前窗口的 layer
- assignChildLayer() 设置子窗口的 layer
// 1 组织, 层级结构
// 2 Surface 和 动画
// 3
class WindowContainer<E extends WindowContainer> {
// 组织
private WindowContainer<WindowContainer> mParent = null;
// 该窗口容器的子节点列表。列表按子节点在屏幕显示的z轴顺序排列, 最上面的窗口容器在列表尾部.
protected final WindowList<E> mChildren = new WindowList<E>();
// 每个WC有一个 Surface
protected SurfaceControl mSurfaceControl;
// 动画
protected final SurfaceAnimator mSurfaceAnimator;
/** The parent leash added for animation. */
private SurfaceControl mAnimationLeash;
final TransitionController mTransitionController;
// Leash 作用
onAnimationLeashCreated();
// 按照index 添加入 mChildren, 同时为 child.setParent(this);
void addChild(E child, int index)
// 按照比较器加入 mChildren
protected void addChild(E child, Comparator<E> comparator)
// 移动一个 child, includingParents递归移动parent
void positionChildAt(int position, E child, boolean includingParents)
}
根容器 RootWindowContainer
RootWindowContainer 是窗口层级的根容器。大遍历从 RootWindowContainer 开始,遍历所有屏幕。
在 WindowManagerService 构造方法中对 RootWindowContainer 进行初始化。
屏幕 DisplayContent
DisplayContent 表示一个屏幕。
SystemServer 创建 AMS 和 WMS,调用 mActivityManagerService.setWindowManager(wm) 开始初始化所有屏幕,并添加为根容器的子窗口,并且同时初始化默认屏幕的 TaskDisplayArea 和 root home task,并添加到其父窗口中。
DisplayContent 类中还管理 应用过渡动画、屏幕配置、屏幕方向、输入法键盘等,以及执行布局。
void setWindowManager(WindowManagerService wm) {
...
// 初始化所有屏幕
final Display[] displays = mDisplayManager.getDisplays();
for (int displayNdx = 0; displayNdx < displays.length; ++displayNdx) {
final Display display = displays[displayNdx];
final DisplayContent displayContent =
new DisplayContent(display, this, mDeviceStateController);
addChild(displayContent, POSITION_BOTTOM);
if (displayContent.mDisplayId == DEFAULT_DISPLAY) {
mDefaultDisplay = displayContent;
}
}
// 同时初始化默认屏幕的 TaskDisplayArea 和 root home task,并添加到父窗口中
final TaskDisplayArea defaultTaskDisplayArea = getDefaultTaskDisplayArea();
defaultTaskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
positionChildAt(POSITION_TOP, defaultTaskDisplayArea.mDisplayContent,
false /* includingParents */);
}
// 应用过渡动画相关
final AppTransition mAppTransition;
final AppTransitionController mAppTransitionController;
boolean mSkipAppTransitionAnimation = false;
final ArraySet<ActivityRecord> mOpeningApps = new ArraySet<>();
final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>();
final ArraySet<WindowContainer> mChangingContainers = new ArraySet<>();
// 输入法键盘相关
WindowState mInputMethodWindow;
private WindowState mImeLayeringTarget;
private InputTarget mImeInputTarget;
屏幕显示区域 DisplayAreas
DisplayAreas 表示一块屏幕显示区域,可以用于分屏。DisplayAreas 可以嵌套。TaskDisplayArea 表示可以包含应用窗口的屏幕显示区域,ImeContainer 表示输入法键盘的显示区域。
DisplayArea 有3种类别,用于确保所包含的窗口有正确的Z轴顺序。其中,ImeContainer 是 ABOVE_TASKS,包含壁纸的 Display 是 BELOW_TASKS。
enum Type {
// 只能包含在应用窗口层级/TASK之上的WindowToken/DisplayArea
ABOVE_TASKS,
// 只能包含在应用窗口层级/TASK之下的WindowToken/DisplayArea
BELOW_TASKS,
// 可以包含任何WindowToken/DisplayArea
ANY;
}
Activity堆栈 Task 和 TaskFragment
TaskFragment 可以包含 ActivityRecord,也可以嵌套。用于管理 Activity 生命周期和可见性。
Task 维护一组相同亲和度的 Activity,可以用于显示最近任务,也可以嵌套。
Root Task 指父窗口不是其它 Task;Leaf Task 指子窗口不是其它 Task。
WindowToken, ActivityRecord, WallpaperWindowToken
ActivityRecord, 应用窗口的令牌; WallpaperWindowToken,壁纸窗口的令牌; WindowToken,其它窗口的令牌;
其成员 windowType 是其子容器窗口的 windowType;
WindowState
表示一个窗口, mBaseLayer,代表窗口Z轴,如果是子窗口类型,这个值是其父窗口的layer mSubLayer,子窗口类型的Z轴