android WMS 详解(二)

一、基础概念

1. 什么是 WMS?它的核心职责是什么?

  • 管理窗口的添加、删除、更新

  • 计算窗口大小和位置(Layout)

  • 管理窗口的层级关系(Z-order)

  • 分配 Surface,与 SurfaceFlinger 协作完成显示

  • 管理窗口动画

  • 处理输入事件的分发

2. WMS 在系统架构中的位置?与 AMS、SurfaceFlinger 的关系?

  • WMS 属于 SystemServer 中的核心服务

  • 与 AMS:AMS 负责 Activity 生命周期管理,WMS 负责 Activity 对应窗口的显示;AMS 通过 WMS 添加/移除窗口

  • 与 SurfaceFlinger:WMS 负责窗口逻辑管理,SurfaceFlinger 负责图层合成与显示;WMS 为每个窗口申请 Surface,SurfaceFlinger 将这些 Surface 合成到屏幕上


二、Window 的添加流程

3. 从 addView() 到 WMS 的完整流程是怎样的?

  • WindowManagerImpl.addView()WindowManagerGlobal.addView()

  • 创建 ViewRootImpl,调用 ViewRootImpl.setView()

  • 通过 IPC 调用 WMS.addWindow()(Session → WMS)

  • WMS 创建 WindowState,检查权限和窗口类型

  • 分配 Surface,建立与 SurfaceFlinger 的连接

  • 执行 performTraversals() 触发测量、布局、绘制

4. WindowTokenAppWindowToken 是什么?

  • WindowToken:窗口的令牌,用于标识一组窗口的归属,是 WMS 中窗口的"身份证"

  • AppWindowToken:继承自 WindowToken,专门用于 Activity 对应的窗口,与 AMS 中的 ActivityRecord 一一对应

5. WindowState 是什么?

  • WMS 中用于表示一个窗口的对象,包含了窗口的所有属性(位置、大小、类型、层级等)

  • 每个通过 WMS 添加的窗口都会对应一个 WindowState


三、窗口层级与类型

6. Android 窗口有哪些类型?层级如何划分?

  • Application Window(1-99):普通应用窗口,如 Activity

  • Sub Window(1000-1999):子窗口,如 Dialog,必须依附于父窗口

  • System Window(2000-2999):系统窗口,如状态栏、Toast、输入法

7. 什么是 typelayer

  • type:窗口类型,决定窗口的基本层级

  • layer:实际计算的层级值,由 type 加上一些调整值(如子窗口的相对位置)计算得出,决定窗口在 Z 轴上的顺序

8. 为什么 Dialog 的 Window 类型是 TYPE_APPLICATION 而不是子窗口?

  • 实际上 Dialog 使用的是 TYPE_APPLICATION,属于应用窗口

  • 但 Dialog 的 token 必须和 Activity 的 token 一致,这是通过 mParentWindow 关联实现的

  • 真正的子窗口(如 PopupWindow)使用 TYPE_APPLICATION_PANEL 等类型


四、测量、布局与绘制

9. performTraversals() 在 WMS 流程中的作用?

  • ViewRootImpl 中的核心方法,触发整个 View 树的遍历

  • 内部调用 measure()layout()draw()

  • 在 WMS 流程中,窗口大小确定后会触发 performTraversals(),进而申请 Surface 并进行绘制

10. WMS 如何确定窗口的大小?

  • 考虑因素:屏幕尺寸、系统装饰(状态栏、导航栏)、窗口的 LayoutParams(宽高、gravity、margin 等)

  • WindowFrames 类记录了窗口的各种边界(parent frame、display frame、content frame 等)

  • 通过 computeFrames() 方法计算最终大小

11. 什么是 mAttachInfo

  • View.AttachInfo 对象,在 ViewRootImpl 中创建

  • 包含了窗口相关的关键信息(如 WindowToken、Surface、硬件加速状态等)

  • 通过 dispatchAttachedToWindow() 传递给 View 树中的每个 View


五、Surface 与显示

12. Surface 是什么时候创建的?

  • ViewRootImpl.relayoutWindow() 中,通过 WMS 的 relayout() 方法请求创建

  • WMS 与 SurfaceFlinger 通信,创建对应的 Layer,返回 Surface 给应用端

  • 应用端通过 Surface.lockCanvas() 获取 Canvas 进行绘制

13. 什么是 SurfaceControl

  • Android 高版本(Android 10+)引入的 Surface 控制类

  • 用于更精细地控制 Surface 的属性(位置、大小、透明度等)

  • 减少了应用层与 SurfaceFlinger 的直接交互,通过 WMS 统一管理

14. 硬件加速与 WMS 的关系?

  • WMS 在创建窗口时会判断是否开启硬件加速

  • 硬件加速使用 RenderThread 进行绘制,最终通过 OpenGL ES 渲染到 Surface

  • WMS 通过 SurfaceControl.Transaction 提交图层变化给 SurfaceFlinger


六、事件分发

15. 触摸事件是如何传递到窗口的?

  • 输入事件由 InputManagerService(IMS)从驱动读取

  • IMS 通过 InputDispatcher 将事件分发给目标窗口

  • WMS 维护着窗口的触摸区域信息,帮助 InputDispatcher 确定事件该发给哪个窗口

  • 最终通过 InputChannel(基于 socket)将事件发送到应用端的 ViewRootImpl

  • 应用端进行事件分发:dispatchTouchEvent()onInterceptTouchEvent()onTouchEvent()

16. 什么是 InputChannel

  • 用于 IMS 与应用程序之间传递输入事件的通道

  • 基于 Unix Domain Socket 实现

  • 在添加窗口时创建,与窗口一一对应


七、Activity 启动与窗口

17. Activity 启动时窗口是如何显示出来的?

  1. AMS 请求 WMS 创建 AppWindowToken

  2. Activity 执行 onCreate()onResume()

  3. ViewRootImpl.setView() 调用 WMS.addWindow()

  4. WMS 创建 WindowState,分配 Surface

  5. 执行 performTraversals() 进行首次绘制

  6. 绘制完成后通知 WMS,WMS 通知 SurfaceFlinger 合成显示

18. 为什么会出现黑屏/白屏?如何优化?

  • 原因:Activity 启动到第一帧绘制完成需要时间,期间显示的是 Window 的背景色

  • 优化方案:

    • 设置 windowBackground 为启动图(Splash Screen 方案)

    • 延迟初始化,减少 onCreate() 工作量

    • 使用 PreviewWindow 机制


八、多窗口与特殊场景

19. 分屏/多窗口模式下 WMS 如何工作?

  • WMS 维护 TaskStackTask 的层级结构

  • 多窗口模式下,窗口的 bounds 不再是全屏,而是根据分屏比例计算

  • WindowContainer 体系(Android 8+)引入了更灵活的容器管理

20. 什么是 WindowContainer

  • Android 8.0 引入的窗口容器体系

  • 包含:WindowContainerRootWindowContainerDisplayContentTaskDisplayAreaTaskActivityRecordWindowTokenWindowState

  • 提供了更清晰的层级管理和遍历能力

21. Toast 为什么使用系统窗口?

  • Toast 使用 TYPE_TOAST(系统窗口类型)

  • 不需要依附于 Activity,可以在应用退出后显示

  • Android 7.0 后限制了普通应用使用 TYPE_TOAST 的权限,防止恶意弹窗


九、高频深入问题

22. Choreographer 与 WMS 的关系?

  • Choreographer 负责接收 VSync 信号,协调动画、输入、绘制的时机

  • WMS 的窗口更新和 SurfaceFlinger 的合成都是基于 VSync 的

  • ViewRootImpl 通过 Choreographer 安排 performTraversals() 的执行

23. 窗口动画是谁负责的?

  • WMS 负责窗口动画的管理(如打开、关闭、切换动画)

  • 通过 WindowAnimatorRemoteAnimationController 实现

  • 动画可以运行在系统进程(WMS)或应用进程(通过 SurfaceControl.Transaction)

24. 如何理解 relayout() 方法?

  • ViewRootImpl 调用 WMS.relayout() 来更新窗口属性

  • 主要工作:重新计算窗口大小、创建/调整 Surface、更新窗口层级

  • 是窗口变化时的核心调度方法

25. Android 12 的 SplashScreen API 与 WMS 的关系?

  • Android 12 系统实现了原生的 SplashScreen 机制

  • WMS 在创建 AppWindowToken 时自动添加 SplashScreen 窗口

  • 应用第一帧绘制完成后,WMS 负责过渡切换

相关推荐
游戏开发爱好者81 小时前
App Store 上传 IPA 自动化,.p8 密钥认证与 CI/CD 接入实战
android·运维·ci/cd·小程序·uni-app·自动化·iphone
游戏开发爱好者83 小时前
iOS 推送怎么配置,APNs 推送证书、设备库与群发
android·ios·小程序·https·uni-app·iphone·webview
wxson728218 小时前
【Android视频监控系统技术总结】
android·音视频
hunterandroid19 小时前
[Android 从零到一] LiveData 粘性事件与单次消费:从重复触发到可靠事件总线
android
hunterandroid19 小时前
[Android 从零到一] Android 事件分发机制:从 ACTION_DOWN 到 View 事件消费链路
android
阿巴斯甜20 小时前
adb‑shell 全套命令实操总结
android
奔跑的架构师21 小时前
[A-49]ARMv9/v8-PSCI接口规范与工作流程简介
android·linux·arm开发·arm
AFinalStone21 小时前
Android 7系统国际化(七)Resources 与 AssetManager 源码剖析
android·国际化·local