Android Framework 中视图的显示流程

Table of Contents

在 Android Framework 层,视图的显示流程涉及系统服务(如 WindowManagerService)、SurfaceFlingerChoreographer 以及 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 渲染与屏幕刷新节奏(避免撕裂/卡顿)。
  • 流程
    1. 应用通过 Choreographer 注册 CALLBACK_TRAVERSAL 回调。
    2. SurfaceFlinger 通过硬件 VSYNC 信号(或软件模拟)周期性触发 Choreographer
    3. 当 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 层行为
    1. Surface 管理
      • 检查是否需要创建/更新 Surface(通过 SurfaceControl)。
      • 通过 Surface.lockCanvas() 获取 Canvas 对象(关联到图形缓冲区)。
    2. 硬件加速
      • 若启用硬件加速,Canvas 实际是 DisplayListCanvas,记录绘制命令(不立即执行)。
      • 最终通过 ThreadedRenderer 将绘制命令提交到 RenderThread 线程。
    3. 缓冲区提交
      • 将绘制完成的图形缓冲区(GraphicBuffer)通过 Surface.unlockCanvasAndPost() 提交到 BufferQueue
      • BufferQueue 是生产者-消费者模型,应用是生产者,SurfaceFlinger 是消费者。

4. SurfaceFlinger 与合成(Composition)

  • SurfaceFlinger 的职责

    1. 从所有窗口的 BufferQueue 中获取图形缓冲区。
    2. 调用 HWC(Hardware Composer) 进行硬件合成(或 GPU 合成)。
    3. 将最终帧提交到显示设备(通过 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 命令(避免阻塞主线程)。
    • 通过 ThreadedRendererDisplayList 转换为 GL 命令。
  • DisplayList 录制
    // ThreadedRenderer.java
    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
        updateRootDisplayList(view); // 将 View 的绘制操作录制为 DisplayList
        nSyncAndDrawFrame(mNativeProxy); // 提交到 RenderThread
    }
    

四、性能关键路径

  1. VSYNC 同步:确保 UI 更新与屏幕刷新频率对齐(60Hz/90Hz/120Hz)。
  2. Jank 避免:若 performTraversals() 耗时超过 16ms(60Hz),会导致掉帧。
  3. 合成策略
    • Client 合成:应用自行合成图层(性能差)。
    • Device 合成:HWC 硬件合成(性能最优)。

五、调试工具与命令

  1. Systrace:分析 performTraversals() 各阶段耗时。
    python systrace.py gfx view wm am ss res -o trace.html
    
  2. dumpsys SurfaceFlinger:查看所有 Surface 的层级和状态。
  3. HWC 日志
    adb shell setprop debug.hwc.log true
    

六、总结

Framework 层的显示流程是 Android 图形系统的核心,涉及:

  1. 多进程协作:应用进程、WindowManagerServiceSurfaceFlinger 通过 Binder 和共享内存通信。
  2. 垂直同步(VSYNC):驱动 UI 更新的节奏。
  3. 硬件加速:通过 RenderThread 和 HWC 最大化性能。
  4. 缓冲区管理BufferQueue 是图形数据传输的基石。

理解这些机制,可以帮助开发者优化 UI 性能、解决卡顿问题,甚至定制 ROM 的显示行为。

明天了解一下 Android Framework 中 input 事件的传递流程