2、窗口管理核心组件:WindowManagerService、DisplayManager、SurfaceFlinger 的角色与关系
好,咱们今天聊聊 Android Automotive 窗口管理的三个核心角色。说实话,这三兄弟的关系,搞懂了,整个窗口系统你就拿下一大半了。
我刚开始接触 IVI 开发时,也经常搞混它们的分工。后来在调试一个多屏异显的 bug 时,才真正理清了脉络。今天我就把这段经验掰开揉碎了讲给你听。
2.1 三个组件,各司其职
先给个总览,让你心里有个谱:
- WindowManagerService(WMS):窗口的「大管家」。管谁该显示、显示多大、在哪显示。
- DisplayManager(DM):屏幕的「资源调度员」。管有多少块屏、每块屏什么参数、怎么连。
- SurfaceFlinger(SF):画面的「终极合成师」。管把所有图层合成一帧,扔给硬件显示。
说白了,WMS 负责「排座次」,DM 负责「定场地」,SF 负责「画大饼」。缺一个,这戏就唱不下去。
2.2 WindowManagerService:窗口的调度中枢
WMS 是 Android 窗口系统的核心服务。它运行在 system_server 进程里,管理着所有应用窗口的生命周期。
它的主要职责包括:
- 窗口的添加、删除、更新:应用通过 Binder 调用 WMS,告诉它「我要显示一个窗口」。WMS 会分配一个
WindowToken,并计算窗口的尺寸和位置。 - 焦点管理:哪个窗口能收到触摸事件?WMS 说了算。我记得在车载场景下,焦点管理特别容易出问题——比如导航和音乐应用抢焦点,导致触摸无响应。
- 输入法窗口管理:键盘弹出来时,WMS 要调整其他窗口的布局,避免被遮挡。
- 窗口动画:窗口打开、关闭、切换时的过渡动画,也由 WMS 协调。
关键点:WMS 不直接绘制任何东西。它只负责「说」,不负责「做」。真正的绘制和合成,是后面两位兄弟的事。
2.3 DisplayManager:屏幕资源的调度员
DisplayManager 管理着所有物理和虚拟显示设备。在车载 IVI 里,这个组件尤其重要——因为车机上通常不止一块屏。
它的核心能力:
- 管理显示设备:主屏、副屏、仪表盘屏、HUD(抬头显示),甚至后排娱乐屏。每个屏幕都有一个唯一的
DisplayId。 - 处理显示配置变化:比如屏幕旋转、分辨率切换、刷新率调整。我遇到过一个问题:车机启动时,副屏的
DisplayInfo还没准备好,WMS 就急着往上面扔窗口,结果窗口显示不全。 - 虚拟显示支持:Android 支持创建虚拟显示(VirtualDisplay),用于屏幕录制、投屏等场景。在车载上,我们用它来做「双屏异显」——主屏显示导航,副屏显示音乐。
避坑指南:我曾经在调试多屏时,发现副屏的触摸坐标总是偏移。查了半天,原来是 DisplayManager 返回的 DisplayInfo 中 logicalDensityDpi 和物理屏幕不匹配。记住:每个屏幕的密度可能不同,WMS 在计算窗口大小时,必须依赖正确的 DisplayInfo。
2.4 SurfaceFlinger:画面的终极合成师
SurfaceFlinger 是 Android 图形系统的核心。它运行在一个独立的 surfaceflinger 进程中,负责将所有应用的 Surface 合成一帧,然后交给硬件显示。
它的工作流程大致如下:
- 接收来自各个应用的 Buffer(通过
BufferQueue)。 - 根据 WMS 提供的窗口层级(Z-order),决定谁在上、谁在下。
- 调用 GPU 或 HWC(硬件合成器)进行合成。
- 将最终画面输出到 DisplayManager 指定的显示设备上。
你想想看,如果 SurfaceFlinger 合成效率低,就会出现掉帧、卡顿。在车载上,这直接影响到用户体验——导航画面卡住,那可是要出事的。
注意:SurfaceFlinger 和 WMS 之间通过 WindowManager 的接口通信。WMS 会告诉 SF:「窗口 A 的 Z-order 是 10,窗口 B 的 Z-order 是 5」。SF 就按这个顺序合成。如果 WMS 传错了顺序,画面就会乱套——比如本该在底层的状态栏,跑到了导航窗口上面。
2.5 三者的协作关系
这三个组件不是各干各的,而是紧密配合。我画个简单的流程给你看:
应用启动 → 请求创建窗口
↓
WMS 分配 WindowToken,计算窗口尺寸
↓
WMS 通知 SurfaceFlinger:创建 Surface,分配 BufferQueue
↓
应用开始绘制,将 Buffer 提交到 BufferQueue
↓
SurfaceFlinger 收到 Buffer,根据 Z-order 合成
↓
SurfaceFlinger 将合成结果交给 DisplayManager 指定的屏幕
↓
屏幕显示最终画面
这个流程里,每一步都依赖前一步的结果。任何一个环节出问题,都会导致显示异常。
2.6 车载场景下的特殊挑战
在 IVI 开发中,这三个组件会遇到一些特殊场景:
- 多屏异显:WMS 需要为每个屏幕维护独立的窗口栈。DisplayManager 要确保每个屏幕的 DisplayInfo 正确。SurfaceFlinger 要同时合成多个输出。
- 安全窗口:比如倒车影像,必须覆盖所有其他窗口。WMS 会把这个窗口的 Z-order 设到最高,SurfaceFlinger 必须保证它不被遮挡。
- 性能要求:车载系统对延迟和帧率要求极高。SurfaceFlinger 的合成策略(GPU vs HWC)直接影响流畅度。
一句话总结:WMS 是「大脑」,决定窗口怎么排;DisplayManager 是「眼睛」,告诉系统有几块屏;SurfaceFlinger 是「手」,把想法变成现实。三者缺一不可,配合好了,才能给用户流畅、稳定的体验。
嗯,这部分内容就到这里。下一章我们会深入 WMS 的窗口管理策略,包括窗口层级、焦点分配和动画机制。到时候再聊。