学习笔记-WMS 简述
在 https://wkmcyz.notion.site/WMS-d85f58e79d294d93ad4b5f6d18188b99 可以获得更好的阅读体验
学习笔记-WMS 简述
WindowManagerService,负责 Android 内 window 的展示管理,类似一个系统级别的 viewGroup。
WMS 的启动和初始化
在 system_server 启动的众多服务中,WMS 是十分重要的一个,和用户 app 以及其他的系统服务都会有很多交互。在 system_server 在 WMS 专门使用的线程上启动了 WMS 之后,WMS 会获取自己完成窗口管理所需要的内部对象。
?? WMS 初始化哪些对象?1)一些逻辑功能类。例如用来完成输入信息捕获的 InputManager 、用来进行绘制的 Choreographer 、 用来执行动画的 WindowAnimator 、 以及用来实现具体的窗口管理策略的 WindowPolicyManager 。
2)一些数据容器类,比如保存 window 对象的表、保存所有令牌对象的表、保存所有用来和 window 交互的 window session 的数组,等。
app & WMS 的交互
应用添加 window 的流程简述
应用获取到 WMS 后,向 WMS 注册一个令牌对象,这个对象可以认为是后需添加的窗口的来源说明。然后使用一个特定的 layoutParam 添加窗口,说明窗口的布局信息以及特点等。窗口触发布局,获取一个 Surface 以用来绘制。在窗口不再使用的时候,移除窗口。在应用不再使用所有窗口的时候,移除其令牌。
?? WindowToken 是什么? Activity 的 token 是什么? 对于 WMS 来说,WindowToken 其实就是一个 Binder 通信的客户端,通过同样的 Binder 添加的 Window 视为该 Binder “产生”的。 在 AMS 创建 Activity 对象的时候,会将 Activity 的 appToken 添加到 WMS,在 Activity 被 AMS 移除的时候,AMS 通知 WMS 移除之。 因为是 AMS 将 appToken 添加到 WMS,所以 AMS 可以通过该 Token 获得 window 的事件回调,因此可以在 window 不可见的时候调用 Activity 的生命周期方法,等。添加窗口到 WMS 的时候,WMS 会判断窗口要添加到哪个显示屏幕上,Android 是可以有多个显示的屏幕的。
WMS 根据窗口的属性判断窗口的展示 z 值,不同类型的窗口其基本值也不同,展示优先级越高的(例如 ANR 提示窗口、输入法窗口)其基本值越大,相同基本值的,通常来说是后加入的窗口会在前面展示,也就是 z 值会大。
WMS 对窗口的布局
WMS 对窗口的布局,指的是 WMS 是如何将管理跌所有窗口进行排列的,这个步骤的输入是所有窗口以及其 layoutParams ,输出则是所有窗口的宽高、窗口在屏幕上的位置以及窗口的 zOrder。
WMS 对一个窗口进行布局,会在窗口的任何属性发生变化的时候进行。这包括 1)窗口的视图属性的变化,如宽高变化、位置变化、layoutParams 变化、可见度变化;2)窗口的状态属性变化,比如窗口被移除,窗口被添加,等。
?? 输入 layoutParams ,输出窗口的位置、大小以及 zOrder 是最重要的内容。除此之外,这个布局过程的输入还包含了窗口对应的应用、窗口类型、窗口测量的宽高、窗口可见性,输出还包含了窗口 Surface 对象的分配。WMS 在对一个窗口进行布局的时候,会检查所有的窗口是否有必要调整。因为某个窗口属性发生变化,可能会影响其他窗口的布局效果。因此 WMS 会对所有的窗口进行统一的关照,以防止其需要修改。
WMS 在布局后得到了窗口的位置以及尺寸,会将各个窗口的实际绘制的大小也设置为这个位置尺寸,后面便会进入每个窗口自己内部的绘制逻辑了(也就是应用的绘制逻辑)
第一步将窗口对象里更新的属性赋值给对应的 WindowState 的属性。后续的操作都依赖最新的 window 属性,因此这一步是必须的。
第二步对其窗口分配的 Surface 进行操作调整。这一步是为了提供正确的窗口绘制的能力。这一步进行的前提是确定了窗口的宽高以及绘制格式,因此需要放到第一步之后。
第三步处理焦点相关的变化。比如焦点窗口从之前的变成新的以后,输入法、壁纸、屏幕的水平或者竖直状态的变化。这一步需要 window 相关的状态,也必须在第一步之后。
第四步则开始对所有的窗口进行重新布局。
?? WMS 里的窗口对象是什么? 这里的窗口对象指的是应用进程窗口在 WMS 里的传输接口对象,负责和实际用户进程的 Window 进行通信。WMS 在内部维护了一份窗口对象到其的映射表。 ?? 窗口和 Surface 窗口布局的时候,窗口和 Surface 并没有实际的关联,WMS 在布局之后得到了每个窗口的坐标信息,然后将每个窗口的尺寸设置为其尺寸。窗口在使用 Surface 进行绘制的时候,并不会有坐标参数的交互。相关类
应用添加 window 到 WMS
- WindowToken , 用来表示应用身份的标识令牌。
- IApplicationToken,Activity 在 WMS 里对应的 token。
- WindowState,WMS 内的 Window 表示。