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 负责过渡切换

相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
ai2work2 天前
ch23 综合复刻:从零做一个最小可用版本(capstone)
kotlin
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
ai2work3 天前
ch21 签名、校验与发版
kotlin
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui