系统服务之WMS

WindowManagerService 简称 WMS ,是系统的核心服务,主要分为四大部分,分别是窗口管理,窗口动画,输入系统中转站和Surface管理


Window

Window是窗口的抽象概念,PhoneWindow是其唯一实现,PhoneWindow中有一个顶级View , DecorView

  • Window是View的管理者(即使用WM操作View,最后是通过ViewRootImpl实现的)
  • View是Window的呈现

WindowManager

WindowManager是个接口,继承自ViewManager

1
2
3
addView(View view, ViewGroup.LayoutParams params);
updateViewLayout(View view, ViewGroup.LayoutParams params);
removeView(View view);
  • WindowManager的实现类是WindowManagerImpl
  • WindowManagerImpl又交给了WindowManagerGlobal
  • WindowManagerGlobal内部使用了ViewRootImpl
WindowManagerGlobal#addView
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
WindowManagerGlobal#addView {
……
//创建viewRoot(一个window对应一个viewRoot)
root = new ViewRootImpl(view.getContext(), display);
……
// RootViewImpl添加view(含window的添加)
root.setView(view, wparams, panelParentView);
……
}

ViewRootImpl#setView{
……
//1.绘制view
//requestLayout内部主要使用垂直同步信号VSync的方式,在收到GPU提供的VSync信号后,会触发View的三大绘制layout,mesure,draw流程
requestLayout();
……
//2.通过session与WMS建立通信:完成window的添加
//WindowManagerService的openSession可以获得session
mWindowSession.addToDisplay(mWindow……);
……
……
}

Session#addToDisplay{
……
mService.addWindow(……)
……
}

即window的添加就交给WindowManagerService了

WindowManagerGlobal#updateViewLayout

1.重新绘制
2.更新window

WindowManagerGlobal#removeView
  1. dispatchDetachedFromWindow()//回调view的dispatchDetachedFromWindow方法
  2. mView.dispatchDetachedFromWindow()
  3. mWindowSession.remove(mWindow)

WindowManagerService

窗口管理:

1.窗口权限检查
2.窗口信息校对
3.获取对应WindowToken
4.窗口有效性检查
5.如果前面满足,则创建一个WindowState对象
6.通过WindowState的attach方法与SurfaceFlinger通信
7.SurfaceFlinger进行渲染输出

输入事件的中转站:

1.启动InputManagerService,同时会创建InputManager
2.创建InputManager同时创建InputReader和InputDispatcher
3.InputReader读取事件
4.InputDispatcher将事件分发给合适的Window
5.WMS会把所有窗口的信息更新到InputDispatcher中
6.Window传到DecorView,然后是android传统事件分发


Activity的Window创建

在ActivityThred的handleResumeActivity()中

1
2
3
4
5
6
7
8
9
10
11
r.activity.makeVisible();
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
//1、windowManager.addView
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
//2、Decor可见
mDecor.setVisibility(View.VISIBLE);
}

Dialog的window创建

1
2
3
4
5
public void show() {
//使用WindowManager.addView
mWindowManager.addView(mDecor, l);
...
}

Toast的window创建

用到了NMS,通过IPC方式来show和定时hide

1
2
3
4
5
6
//Toast构造方法创建TN实例
TN#handleShow(){
……
mWM.addView(mView, mParams);
……
}

补充

Activity#attach

mWindow = new PhoneWindow(this, window, activityConfigCallback);
创建了一个PhoneWindow,并传入当前Activity的this对象,Window得到Activity的引用,由此就建立了Window和Activity的联系。

PhoneWindow#setContentView

installDecor()
给当前Activity的Window创建了一个DecorView,由此就建立了Window和View的联系。

窗口类型

1.应用程序窗口(Application Window)
Activity,类型为:1-99
2.子窗口(Sub Window)
PopupWindow,Dialog,类型为:1000-1999
3.系统窗口(System Window)
输入法窗口,系统错误提示窗口,Toast等,类型为:2000到2999


WMS知识点

Window中有容器和树的概念
  • WMS中有WindowContainer类来实现容器机制
  • 树:每个容器在作为父容器的时候,同时也可能是其他容器的子容器

class WindowContainer implements Comparable {
… private WindowContainer mParent = null;//1
protected final WindowList mChildren = new WindowList();//2
}

注释1处mParent是当前WindowContainer容器的父容器

注释2处的mChildren是一个继承WindowContainer的集合对象,说明当前WindowContainer可能会有好几个子容器。

窗口管理

DisplayContent

一个DisplayContent代表一个屏幕
DisplayContent内部使用:IBinder为key,WindowToken为value的键值对保存在HashMap中

WindowToken

其子容器是WindowState

1.应用组件标识:将属于同一个应用组件的窗口组织在一起,这里的应用组件可以是:Activity
2.令牌作用:应用组件在需要更新窗口时,需要向WMS提供令牌表明自己的身份

但是系统窗口是个例外,并不需要提供token,WMS会隐式声明一个WindowToken,不过需要申明系统权限

WindowState

代表一个window,其内部保存了一个Window所有的属性信息
其也是打通IMS的关键

窗口动画

核心类:
WindowStateAnimator管理动画
WindowAnimator窗口动画以及Surface操作的单例工具类

输入事件处理

核心类:
InputChannel(底层:Socket)

Surface管理

Surface的创建:WindowSurfaceController

ViewRootImpl中创建空对象Surface,WMS负责填充Surface和摆放,之后将Surface提交给SurfaceFlinger进行合并

1
2
3
4
5
6
7
8
ViewRootImpl#relayoutWindow
Session#relayout
WMS#relayoutWindow
WMS#createSurfaceControl
WindowStateAnimator#createSurfaceLocked
WindowSurfaceController#构造函数
SurfaceControl#构造函数
SurfaceControl#nativeCreate
Surface的摆放:WindowSurfacePlacer
1
2
3
4
WindowSurfacePlacer#performSurfacePlacement
WindowSurfacePlacer#performSurfacePlacementLoop
……
WindowSurfaceController#showRobustly

将Surface提交给SurfaceFlinger进行合成并显示在屏幕上,⼀个Surface对应SF进程中的⼀个 Layer


参考:https://juejin.cn/post/7172598258064162830