WindowManagerService 类的工作流程详细介绍

一、窗口创建流程

  1. 请求接收
    • 当应用程序(通过 Activity 或者其他窗口组件)需要创建一个新窗口时,会通过 WindowManager 接口向 WMS 发送请求。这个请求会通过 Binder 机制传递到 WindowManagerService 类。例如,在 Activity 的 onCreate 方法中调用 setContentView 方法,最终会触发这个创建窗口的请求。
    • 此时,WMS 就像一个窗口 “接待员”,开始处理这个请求。它会先检查请求的合法性,确保只有符合系统安全和策略要求的窗口才能被创建。
  2. 权限验证
    • WMS 通过 mPolicy.checkAddPermission 方法进行权限验证。这一步就像是在门口设置的 “安检关卡”,只有通过权限验证的窗口请求才能进入下一步的创建流程。如果权限验证失败,例如应用程序没有足够的权限创建特定类型的窗口,那么将立即终止添加过程,防止非法或不符合系统规定的窗口出现。
  3. 创建 WindowToken(部分情况)
    • 对于一些系统窗口(如输入法窗口),需要主动创建 WindowToken。这通常由特定的服务(如 InputMethodManagerService)来完成。WindowToken 就像是窗口的 “身份证”,用于标识窗口所属的应用程序或任务。在创建窗口的过程中,这个步骤确保了窗口身份的唯一性和安全性。
  4. 创建 WindowState 实例
    • WMS 为新窗口创建 WindowState 实例。WindowState 是 WMS 中表示窗口状态的核心对象,负责管理窗口的各种属性和状态,如位置、大小、透明度等。这个实例就像是为新窗口建立的一个 “信息档案”,记录了窗口从创建到销毁过程中的所有重要信息。
  5. 添加到 DisplayContent
    • WMS 将新创建的 WindowState 添加到相应的 DisplayContent 中。DisplayContent 负责管理特定物理显示设备上的所有窗口信息,它就像是一个 “窗口仓库”,将不同的窗口按照一定的规则存储起来。这样可以方便 WMS 对窗口进行管理,特别是在处理多屏幕或者多窗口场景时,能够有效地组织和管理窗口的显示。
  6. 布局计算
    • WMS 会根据窗口的属性(如类型、大小要求等)和系统的配置(如屏幕分辨率、方向等)计算窗口的布局信息,包括位置、大小等。这一步就像是一个 “空间规划师”,为窗口在屏幕上找到最合适的 “居住空间”,确保窗口能在屏幕上正确显示。例如,对于一个普通的应用程序窗口,它会根据屏幕的可用空间和窗口的优先级,计算出一个合适的位置和大小,使得窗口既能够完整显示内容,又不会与其他窗口产生冲突。
  7. 创建 SurfaceControl
    • WMS 为窗口创建 SurfaceControl 对象。SurfaceControl 是 SurfaceFlinger 用于管理窗口显示的核心组件,它就像是一个 “显示控制器”,负责管理窗口的显示层级和属性。通过创建 SurfaceControl,WMS 为窗口的显示做好了准备工作,将窗口的显示控制权交给了 SurfaceControl。
  8. 提交 SurfaceControl
    • WMS 将创建好的 SurfaceControl 提交给 SurfaceFlinger。SurfaceFlinger 是 Android 系统中负责图形合成和显示的重要组件,它就像一个 “舞台导演”,将各个窗口的内容组合在一起并显示在屏幕上。这一步骤完成了窗口的实际显示准备,使得窗口的内容能够通过 SurfaceFlinger 最终呈现在屏幕上。
  9. 完成绘制与显示窗口
    • WMS 调用 WindowState 的 finishDraw 方法,完成窗口的绘制过程。这标志着窗口在内容绘制方面已经准备就绪。然后,WMS 通过调用 WindowState 的 prepareSurface 方法,最终将窗口显示在屏幕上。此时,用户就可以看到新创建的窗口出现在屏幕上了。

二、窗口更新流程

  1. 请求接收与权限验证
    • 当应用程序通过 WindowManager 接口发出更新窗口的请求时,WMS 首先会接收这个请求。然后,它会像创建窗口时一样,通过验证权限来确保请求的合法性。只有通过权限验证的请求,才能进行后续的窗口更新操作。这一步是为了防止未经授权的应用程序对窗口进行非法修改。
  2. 获取目标 WindowState
    • 经过权限验证后,WMS 会获取目标 WindowState。因为 WindowState 记录了窗口的所有状态信息,所以 WMS 需要通过这个对象来更新窗口的相关属性。这就好比要修改一个人的档案信息,首先要找到对应的档案一样。
  3. 更新 WindowState 字段
    • 根据新的属性值,WMS 更新 WindowState 的相关字段。例如,如果窗口的大小发生了变化,WMS 会更新 WindowState 中的 width 和 height 属性;如果位置发生了变化,则更新 x 和 y 坐标属性。这些更新后的属性信息会被用于后续的显示调整。
  4. 调整窗口层级(如有必要)
    • 当窗口的更新涉及到层级变化时,例如窗口的 Z – Order 值改变,WMS 会调整窗口在层级树中的位置。这是为了确保窗口之间的正确叠加关系,保证窗口的显示顺序符合用户的预期和系统的规则。
  5. 通知 SurfaceFlinger 重新绘制
    • 最后,WMS 通知 SurfaceFlinger 重新绘制窗口。因为窗口的属性发生了变化,所以需要重新绘制窗口的内容,以反映这些变化。SurfaceFlinger 会根据 WMS 提供的新的窗口属性和内容信息,重新合成和显示窗口,使得用户能够看到更新后的窗口效果。

三、窗口销毁流程

  1. 应用端触发与请求发送
    • 通常在 Activity 的 onDestroy () 方法中开始窗口的移除过程。这是因为当 Activity 结束时,与之相关的窗口也不再需要显示。应用程序会通过 IWindowSession 接口向 WMS 发送移除请求,这个接口就像是应用程序和 WMS 之间的 “通信管道”,负责传递移除窗口的请求。
  2. WMS 处理与 Surface 资源释放
    • WMS 接收到请求后,会调用 WindowState 的 removeIfPossible () 方法,尝试移除窗口。同时,它会释放与窗口关联的 Surface 资源。Surface 资源的释放就像是清理一块用过的画布,避免资源浪费,为系统腾出更多的资源用于其他操作。
  3. 状态更新与容器清理
    • WMS 会更新 WindowState 的 mRemoveFlags 标志位,标记窗口已被移除。然后,从 DisplayContent 中移除窗口,清理窗口在层级树中的位置。这就好比把一个已经处理完的物品从仓库的货架上移除,使得仓库(DisplayContent)的空间得到合理利用,并且系统的窗口管理结构能够保持整洁和高效。

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注