作为Android窗口系统的核心设计,WindowManager.addView()
添加 DecorView
的流程涉及 应用进程与系统服务(WMS)的跨进程协作 以及 图形显示系统的联动。以下是源码分析:
1. 添加的终点:WMS 管理的窗口层级
DecorView 最终被添加到 WindowManagerService (WMS) 维护的全局窗口列表 中,并通过 SurfaceFlinger 渲染到屏幕。关键步骤在 ViewRootImpl
中完成:
源码路径:
WindowManagerGlobal.addView()
→ViewRootImpl.setView()
→WindowSession.addToDisplay()
(IPC) →WMS.addWindow()
2. 核心流程源码解析
(1) 应用进程:WindowManagerGlobal.addView()
java
// WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params, ...) {
ViewRootImpl root = new ViewRootImpl(context, display); // 创建ViewRootImpl
root.setView(view, wparams, panelParentView); // 关键:关联DecorView
}
(2) ViewRootImpl.setView()
:连接DecorView与WMS
java
// ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
mView = view; // 持有DecorView实例
requestLayout(); // 触发布局
res = mWindowSession.addToDisplayAsUser(...); // IPC调用WMS!
}
mWindowSession
:IWindowSession.Stub
的代理对象,通过 Binder IPC 与 WMS 通信。
(3) WMS 处理窗口添加:WMS.addWindow()
java
// WindowManagerService.java
public int addWindow(Session session, IWindow client, ...) {
WindowState win = new WindowState(...); // 创建窗口状态对象
win.attach(); // 建立与客户端的连接
mWindowMap.put(client.asBinder(), win); // 存入全局Map
win.addWindowToListInOrderLocked(); // 根据Z-order排序
WindowSurfaceController surfaceController = win.createSurfaceLocked(); // 创建Surface!
}
IWindow client
:由ViewRootImpl.W
(Binder对象) 实现,用于 WMS 回调应用进程。WindowState
:WMS 中代表一个窗口的核心类,管理窗口状态、层级、动画等。
3. 显示的关键:Surface 的创建与绘制
(1) WindowState.createSurfaceLocked()
java
// WindowState.java
void createSurfaceLocked() {
mWinAnimator.createSurfaceLocked(); // 委托给WindowSurfaceController
}
// WindowSurfaceController.java
void createSurface() {
mSurface = new Surface(); // 创建Surface对象
Session.windowAddedLocked(...); // 通过SurfaceFlinger申请图形缓冲区
}
Surface
:代表一个图形缓冲区,由 SurfaceFlinger 分配和管理。
(2) ViewRootImpl
触发绘制
java
// ViewRootImpl.java
void performTraversals() {
performMeasure(); // 测量
performLayout(); // 布局
performDraw(); // 绘制
}
private void performDraw() {
draw(fullRedrawNeeded); // 触发硬件/软件绘制
}
private void draw(boolean fullRedrawNeeded) {
Surface surface = mSurface; // 从WMS申请的Surface
Canvas canvas = surface.lockCanvas(dirty); // 获取Canvas
mView.draw(canvas); // DecorView绘制内容到Canvas
surface.unlockCanvasAndPost(canvas); // 提交缓冲区到SurfaceFlinger!
}
unlockCanvasAndPost()
:通过 BufferQueue 将图形缓冲区提交给 SurfaceFlinger 合成。
4. 显示到屏幕:SurfaceFlinger 合成
-
应用进程 :通过
Surface.unlockCanvasAndPost()
将帧数据放入BufferQueue
。 -
SurfaceFlinger:
- 在 VSYNC 信号到达时,从所有窗口的
BufferQueue
中取帧。 - 根据 WMS 提供的窗口层级(Z-order) 进行图层合成。
- 将最终帧输出到 FrameBuffer 显示到屏幕。
- 在 VSYNC 信号到达时,从所有窗口的
关键设计总结
组件 | 作用 |
---|---|
DecorView |
窗口的根视图,承载UI内容,但自身不直接显示。 |
ViewRootImpl |
连接 DecorView 与 WMS 的桥梁,负责测量、布局、绘制及IPC通信。 |
WMS |
系统服务,管理所有窗口状态(WindowState)、层级和动画。 |
Surface |
由 WMS 申请,SurfaceFlinger 分配的实际图形缓冲区,视图内容绘制于此。 |
SurfaceFlinger |
系统服务,合成所有窗口的 Surface,输出到屏幕。 |
为何能显示?核心链条
- 窗口注册 :
ViewRootImpl
通过 IPC 将DecorView
添加到 WMS 的窗口树。 - Surface 分配:WMS 向 SurfaceFlinger 申请图形缓冲区(Surface)。
- 视图绘制 :
ViewRootImpl
将DecorView
内容绘制到 Surface。 - 缓冲区提交 :通过
unlockCanvasAndPost()
提交帧到 SurfaceFlinger。 - 图层合成:SurfaceFlinger 根据 WMS 提供的 Z-order 合成所有窗口的 Surface。
- 显示输出:合成后的帧通过 FrameBuffer 输出到物理屏幕。
关键点 :
DecorView
本身只是一个普通 View 树,其显示能力完全依赖于 WMS 分配的 Surface 和 ViewRootImpl 的绘制提交机制。跨进程协作(应用 ↔ WMS ↔ SurfaceFlinger)是实现窗口显示的核心基础。