Android WindowManager:窗口管理、事件分发与底层通信

523 阅读2分钟

Android WindowManager:窗口管理、事件分发与底层通信


一、WindowManager 的核心功能:窗口生命周期管理

WindowManager 是一个位于应用进程的接口,它是开发者与 Android 窗口管理系统进行交互的唯一入口。它负责管理窗口的整个生命周期:从创建到更新再到销毁。

1. 添加窗口(addView

  • 功能addView 方法用于将一个 View 添加到屏幕上,创建一个新的窗口。
  • 场景:创建悬浮窗(Floating Window)、自定义 ToastDialog
  • 底层原理WindowManager 通过 Binder IPCSystemServer 进程中的 WindowManagerService(WMS)发送一个创建窗口的请求。WMS 负责在系统层面创建窗口,并分配一个 Surface 作为绘制的画布。

2. 更新窗口(updateViewLayout

  • 功能updateViewLayout 方法用于动态修改窗口的布局参数(LayoutParams)。
  • 场景:拖动悬浮窗、动态调整窗口大小或透明度。
  • 底层原理WindowManager 会将修改后的 LayoutParams 对象发送给 WMS。WMS 随后会根据新的参数调整窗口的位置和尺寸,并触发相应的重绘。

3. 删除窗口(removeView

  • 功能removeView 方法用于将一个 View 从屏幕上移除,并销毁其关联的窗口。
  • 场景:关闭悬浮窗、页面销毁时清理残留 View
  • 底层原理WindowManager 向 WMS 发送一个销毁窗口的请求。WMS 接收到请求后,会销毁窗口、回收其 Surface,并释放所有相关资源。

二、窗口参数(LayoutParams):窗口行为的配置器

WindowManager.LayoutParams 是一个配置对象,它定义了窗口的行为、外观和位置。

  • type:决定窗口在屏幕上的层级(Z-order)。

    • TYPE_APPLICATION_OVERLAY:用于悬浮窗,其层级高于应用窗口。
    • TYPE_TOAST:用于系统提示,层级高于悬浮窗。
  • flags:控制窗口的特性。

    • FLAG_NOT_FOCUSABLE:窗口不获取焦点,可以实现点击穿透效果。
    • FLAG_LAYOUT_NO_LIMITS:允许窗口突破屏幕边界进行绘制。
  • gravity:定义窗口在屏幕上的对齐方式。


三、悬浮窗开发与陷阱

悬浮窗是 WindowManager 最典型的应用场景之一,但其开发也充满了陷阱。

  • 权限问题:创建悬浮窗需要 android.permission.SYSTEM_ALERT_WINDOW 权限。在 Android 6.0 及以上版本,该权限是危险权限,需要动态申请,并引导用户到设置页面手动开启。
  • 内存泄漏:悬浮窗的生命周期独立于 Activity。如果悬浮窗没有被及时移除,它会持有 ActivityContext 的引用,导致内存泄漏。最佳实践是在 ActivityonDestroy() 方法中调用 windowManager.removeView()
  • 层级问题:如果悬浮窗的 type 设置不当,可能会被其他窗口覆盖。