第七章 理解 WindowManager.md
7.1 Window、WindowManager 和 WMS
Window 是抽象的概念,其实体体现还是 View,而 WindowManager 用于管理各个 Window,WindowManager 对 View 的各种操作最终都会有 WMS 处理。
7.2 WindowManager 的关联类
其中 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 变量定义,其中三种类型分别对应三种范围:
数值越大,该 Window 的显示位置就越靠近用户,当然如果两个 WIndow 的次序一致,则 WMS 会结合各种情况判断出最终的显示次序。
7.3.2 Window 的标志
设置 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 软键盘相关模式
主要是当软键盘弹出时候的相关模式:
可以在 AndroidManifest 文件中给 Activity 定义相关 flag,也可在代码中直接调用 window#setSoftInputMode 方法直接设置
7.4 Window 的操作
对 WIndow 的操作分为 WindowManager 处理部分与 WMS 处理部分 ,其中 WMS 对三种类型的 WIndow 一视同仁 。
这里抓哟分析 WindowManager 的处理部分
7.4.1 系统窗口的添加过程
这里以 StatusBar 的添加过程为例:
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 通讯进而进行某些操作的抽象。
其中 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 的操作 。