Android Framework 中视图的显示流程
Table of Contents
在 Android Framework 层,视图的显示流程涉及系统服务(如
WindowManagerService
)、SurfaceFlinger
、Choreographer
以及ViewRootImpl
等核心组件的深度协作。以下是完全基于 Framework 层的详细流程解析,聚焦于系统级机制而非 SDK 层的View/ViewGroup
实现。
一、整体框架层级
+----------------+ +----------------+ +----------------+ +----------------+
| 应用进程 | | SurfaceFlinger| | Display | | 硬件驱动 |
| (App Process) | <--> | (System Server)| <--> | (HWC) | <--> | (Display Driver)|
+----------------+ +----------------+ +----------------+ +----------------+
| | |
| Binder IPC | BufferQueue | 帧同步信号
| (WindowManagerService) | (Gralloc) | (VSYNC)
v v v
二、Framework 层核心流程详解
1. UI 变更的触发
- 场景:当应用调用
View.invalidate()
或requestLayout()
时,触发视图更新。 - Framework 入口:
ViewRootImpl
(每个窗口的视图树管理者)的scheduleTraversals()
方法。// ViewRootImpl.java void scheduleTraversals() { if (!mTraversalScheduled) { mTraversalScheduled = true; // 通过 Choreographer 注册 VSYNC 回调 mChoreographer.postCallback( Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null); } }
2. VSYNC 信号与 Choreographer
- Choreographer 的作用:协调 UI 渲染与屏幕刷新节奏(避免撕裂/卡顿)。
- 流程:
- 应用通过
Choreographer
注册CALLBACK_TRAVERSAL
回调。 SurfaceFlinger
通过硬件 VSYNC 信号(或软件模拟)周期性触发Choreographer
。- 当 VSYNC 信号到达时,
Choreographer
回调mTraversalRunnable
,触发performTraversals()
。
- 应用通过
3. performTraversals() 的三大阶段
ViewRootImpl.performTraversals()
是 Framework 层处理视图更新的核心方法,分为三个阶段:
(1) Measure 阶段(测量)
- Framework 层行为:
- 通过
WindowManagerService
获取窗口的WindowManager.LayoutParams
(如宽高、FLAG)。 - 结合
Display
的物理尺寸和窗口参数,生成根视图的MeasureSpec
。 - 递归调用视图树的
measure()
方法(最终调用到应用层的View.onMeasure()
)。
- 通过
- 关键对象:
WindowManagerService
:管理窗口的全局状态(如 Z-Order、焦点)。DisplayMetrics
:屏幕的物理参数(密度、分辨率)。
(2) Layout 阶段(布局)
- Framework 层行为:
- 根据测量结果和窗口属性(如 Gravity),计算根视图的位置。
- 递归调用视图树的
layout()
方法(最终调用到应用层的View.onLayout()
)。
- 关键对象:
WindowManagerGlobal
:管理所有窗口的全局状态。
(3) Draw 阶段(绘制)
- Framework 层行为:
- Surface 管理:
- 检查是否需要创建/更新
Surface
(通过SurfaceControl
)。 - 通过
Surface.lockCanvas()
获取Canvas
对象(关联到图形缓冲区)。
- 检查是否需要创建/更新
- 硬件加速:
- 若启用硬件加速,
Canvas
实际是DisplayListCanvas
,记录绘制命令(不立即执行)。 - 最终通过
ThreadedRenderer
将绘制命令提交到 RenderThread 线程。
- 若启用硬件加速,
- 缓冲区提交:
- 将绘制完成的图形缓冲区(
GraphicBuffer
)通过Surface.unlockCanvasAndPost()
提交到BufferQueue
。 BufferQueue
是生产者-消费者模型,应用是生产者,SurfaceFlinger
是消费者。
- 将绘制完成的图形缓冲区(
- Surface 管理:
4. SurfaceFlinger 与合成(Composition)
-
SurfaceFlinger 的职责:
- 从所有窗口的
BufferQueue
中获取图形缓冲区。 - 调用 HWC(Hardware Composer) 进行硬件合成(或 GPU 合成)。
- 将最终帧提交到显示设备(通过 DRM/KMS 驱动)。
- 从所有窗口的
-
关键流程:
// SurfaceFlinger.cpp void SurfaceFlinger::handleMessageRefresh() { // 1. 合成所有层(Layer) preComposition(); rebuildLayerStacks(); setUpHWComposer(); doComposition(); // 调用 HWC 或 GPU 合成 // 2. 提交到显示设备 postComposition(); }
5. 显示到屏幕
- HWC(Hardware Composer):
- 硬件模块(如高通、MTK 的显示驱动)负责高效合成图层(避免 GPU 计算)。
- 支持叠加层(Overlay)、旋转、缩放等硬件优化操作。
- 显示时序:
- HWC 确保在下一个 VSYNC 信号到来时,新帧被显示(避免撕裂)。
三、核心系统组件详解
1. WindowManagerService (WMS)
- 职责:
- 管理所有窗口的 Z-Order、焦点、动画。
- 与
ActivityManagerService
协作处理窗口生命周期。
- 关键机制:
- 窗口令牌(WindowToken):标识窗口的归属(如 Activity、Dialog)。
- 窗口策略(WindowPolicy):控制窗口的显示规则(如锁屏遮挡)。
2. Surface 与 BufferQueue
- Surface:
- 每个窗口对应一个
Surface
,是应用与SurfaceFlinger
交换图形数据的接口。 - 内部通过
BufferQueue
管理图形缓冲区(GraphicBuffer
)。
- 每个窗口对应一个
- BufferQueue 工作流程:
应用 (Producer) SurfaceFlinger (Consumer) | | |-- dequeueBuffer() <-----------| 请求空闲缓冲区 |-- queueBuffer() ------------->| 提交已绘制的缓冲区 | |-- acquireBuffer() 获取缓冲区 | |-- releaseBuffer() 释放缓冲区
3. RenderThread 与硬件加速
- RenderThread:
- 独立的渲染线程,负责执行 GPU 命令(避免阻塞主线程)。
- 通过
ThreadedRenderer
将DisplayList
转换为 GL 命令。
- DisplayList 录制:
// ThreadedRenderer.java void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) { updateRootDisplayList(view); // 将 View 的绘制操作录制为 DisplayList nSyncAndDrawFrame(mNativeProxy); // 提交到 RenderThread }
四、性能关键路径
- VSYNC 同步:确保 UI 更新与屏幕刷新频率对齐(60Hz/90Hz/120Hz)。
- Jank 避免:若
performTraversals()
耗时超过 16ms(60Hz),会导致掉帧。 - 合成策略:
- Client 合成:应用自行合成图层(性能差)。
- Device 合成:HWC 硬件合成(性能最优)。
五、调试工具与命令
- Systrace:分析
performTraversals()
各阶段耗时。python systrace.py gfx view wm am ss res -o trace.html
- dumpsys SurfaceFlinger:查看所有 Surface 的层级和状态。
- HWC 日志:
adb shell setprop debug.hwc.log true
六、总结
Framework 层的显示流程是 Android 图形系统的核心,涉及:
- 多进程协作:应用进程、
WindowManagerService
、SurfaceFlinger
通过 Binder 和共享内存通信。 - 垂直同步(VSYNC):驱动 UI 更新的节奏。
- 硬件加速:通过 RenderThread 和 HWC 最大化性能。
- 缓冲区管理:
BufferQueue
是图形数据传输的基石。
理解这些机制,可以帮助开发者优化 UI 性能、解决卡顿问题,甚至定制 ROM 的显示行为。
明天了解一下 Android Framework 中 input 事件的传递流程