第七章 理解 WindowManager.md

何言 2021年10月22日 135次浏览

7.1 Window、WindowManager 和 WMS

image20211002162619960.png

Window 是抽象的概念,其实体体现还是 View,而 WindowManager 用于管理各个 Window,WindowManager 对 View 的各种操作最终都会有 WMS 处理。

7.2 WindowManager 的关联类

image20211002162852588.png

其中 WindowManagerGlobal 为单例模式,一个进程只会存在一个实例,而 WindowManagerImpl 的所有功能都委托给 WindowMnagerGlobal 实现

7.3 Window 的属性

Window 的属性由多种,其中有三种与应用开发关系密切,分别是 Type,Flag 和 SoftInputMode

7.3.1 Window 的类型和显示次序

总的来说 Window 有三大类型,Application Window、Sub Window 和 System Window,其都在 WindowManager 的静态内部类 LayoutParams 中被定义。

类型由一个 类似 Z 轴的 int 变量定义,其中三种类型分别对应三种范围:

image20211002164512562.png

image20211002164521963.png

image20211002164534824.png

数值越大,该 Window 的显示位置就越靠近用户,当然如果两个 WIndow 的次序一致,则 WMS 会结合各种情况判断出最终的显示次序。

7.3.2 Window 的标志

image20211002170023125.png

设置 Window 的 Flag 有 3 种方法

// 1
mWindow.addFlags(xx);

// 2
mWindow.setFlags(flag1, falg2);

// 3
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.flgs = flag1 | flag2;
mWindow.addView(view, params);

7.3.3 软键盘相关模式

主要是当软键盘弹出时候的相关模式:

image20211002170508519.png

可以在 AndroidManifest 文件中给 Activity 定义相关 flag,也可在代码中直接调用 window#setSoftInputMode 方法直接设置

7.4 Window 的操作

对 WIndow 的操作分为 WindowManager 处理部分与 WMS 处理部分 ,其中 WMS 对三种类型的 WIndow 一视同仁 。

image20211002170946356.png

这里抓哟分析 WindowManager 的处理部分

7.4.1 系统窗口的添加过程

这里以 StatusBar 的添加过程为例:

image20211002171456552.png

WindowManagerGlobal 中维护了和 Window 操作相关的 3 个列表,分别是

  • View 列表 ArrayList<View>
  • 布局参数列表 ArrayList<WindowManager.LayoutParams>
  • ViewRootImpl 列表 ArrayListr<ViewRootImpl>

其中 ViewRootImpl 有以下职责:

  • View 树的 根 并管理 View 树
  • 触发 View 的测量、布局和绘制
  • 输入事件中转站
  • 管理 Surface
  • 负责与 WMS 通讯

这里 ViewRootImpl 并不是只有真正的 View 根才有,而是所有 View 都有一个自己的对应 ViewRootImpl 对象,每当你想要以该 View 为根进行一些操作时都可以拿到其 View 的 ViewRootImpl 对象,感性的理解,是把当前 View 作为 某棵子树的根来与 WMS 通讯进而进行某些操作的抽象。

image20211002173808858.png

其中 ViewRootImpl 与 WMS 的 IPC 通讯采用 Binder,其 AIDL 的抽象接口是 Session,WMS 中维护了多个 Session,用于发送消息给多个 APP 进程,而 App 进程中 ViewRootImpl 持有 IWindowSession 对象(实际上是代理对象),用于发消息给 WMS 。

当我们 ViewRootImpl 调用 addToDisplay 方法时,WMS 会收到其消息,并将界面会为该 Window 分配 Surface,而 WMS 将其维护的 Surface 交给 SurfaceFlinger 处理。 SurfaceFlinger 会将所有 Surface 混合并会绘制到屏幕上。

7.4.2 Activity 的添加过程 (PAS)

7.4.3 Window 的更新过程

当我们调用 ViewManager 的 updateViewLayout 方法时,实际上是调用 WindowManagerImpl 中的该方法,最终会委托到 WindowManagerGlobal 中的 该方法。

该方法会更新对应的列表,然后找到对应 View 的 ViewRootImpl ,然后调用其 setLayoutParams 方法,该方法最终会调用 ViewRootImpl 中 scheduleTranversals 方法,方法中会想 mChoreographer 传入一个回调,该回调会在下一帧被渲染时执行,回调中会调用 VieRootImpl 的 doTraversal 方法,该方法会调用 performTraversals 方法。

该方法会开始该 View 的工作流程,包括 测量,布局与绘制。

7.5 小结

本章讲了 WindowManager 关联表,Window 的属性和 Window 的操作 。