浅谈View经GPU渲染绘制的过程

咱们今天就用一个超有趣的故事来理解Android的View绘制原理。准备好了吗?

故事开始:UI王国的"画展"筹备记

想象一下,Android系统就像一个庞大的UI王国,每次打开App就像举办一场画展。

角色介绍:

  • ViewRootImpl:画展总策划(大管家)
  • DecorView:画展的巨型画布
  • View/ViewGroup:各种画家和画师小组
  • Choreographer:动画导演(负责节奏)
  • SurfaceFlinger:最终展厅布置师
  • CPU/GPU:画家们的双手

第一幕:画展的启动(Activity创建)

java 复制代码
// 王国收到举办画展的指令
public class Activity {
    public void onCreate() {
        setContentView(R.layout.main); // "准备画布和颜料!"
    }
}

当Activity创建时,PhoneWindow会准备DecorView这个"巨型画布",然后通过LayoutInflater把XML布局变成一个个View对象。

第二幕:三大核心流程 - 画展筹备三部曲

1. 测量(Measure)- "量尺寸"

总策划ViewRootImpl大喊:"各位画家,报上你们的尺寸!"

java 复制代码
// ViewRootImpl.java
private void performTraversals() {
    // 第一步:测量
    performMeasure();
    // 第二步:布局
    performLayout();
    // 第三步:绘制
    performDraw();
}

// 测量过程 - 递归测量所有View
private void performMeasure() {
    int childWidthMeasureSpec = ...;
    int childHeightMeasureSpec = ...;
    mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

每个View的measure方法:

java 复制代码
// View.java
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
    onMeasure(widthMeasureSpec, heightMeasureSpec); // 自定义测量逻辑
    // 测量完成后,mMeasuredWidth/mMeasuredHeight就有值了
}

有趣比喻:就像画家们互相商量:"我要占多大地方?你有多宽?我有多高?"

2. 布局(Layout)- "定位置"

"现在开始布置展位!每个人站在哪里?"

java 复制代码
// ViewGroup.java
@Override
public final void layout(int l, int t, int r, int b) {
    // 先确定自己的位置
    super.layout(l, t, r, b);
    // 再安排子View的位置
    layoutChildren();
}

protected void layoutChildren() {
    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        // 计算每个子View的位置
        child.layout(childLeft, childTop, childRight, childBottom);
    }
}

3. 绘制(Draw)- "动笔作画"

"各就各位,开始画画!"

java 复制代码
// View.java
public void draw(Canvas canvas) {
    // 步骤1:画背景
    drawBackground(canvas);
    // 步骤2:画自己(核心)
    onDraw(canvas);
    // 步骤3:画子View
    dispatchDraw(canvas);
    // 步骤4:画装饰(滚动条、前景等)
    onDrawForeground(canvas);
}

第三幕:同步与渲染 - 动画导演登场

Choreographer(动画导演)负责保持60fps的流畅节奏:

java 复制代码
// Choreographer.java
public void onVsync() {
    // 垂直同步信号到来!
    mHandler.post(mTraversalRunnable);
}

final class TraversalRunnable implements Runnable {
    public void run() {
        doTraversal(); // 执行遍历(测量-布局-绘制)
    }
}

第四幕:硬件加速 - GPU大神出手

现代Android使用硬件加速,就像请来了GPU这位"神笔马良":

java 复制代码
// ThreadedRenderer.java(硬件渲染器)
@Override
void draw(View view, AttachInfo attachInfo) {
    // 1. 创建DisplayList(绘制指令列表)
    updateRootDisplayList(view);
    // 2. 同步到RenderThread
    nSyncAndDrawFrame(mNativeProxy);
}

DisplayList就像给GPU的"绘画说明书",避免重复计算。

第五幕:最终展示 - SurfaceFlinger布展

cpp 复制代码
// SurfaceFlinger.cpp(Native层)
void SurfaceFlinger::composite() {
    // 收集所有Layer(图层)
    for (auto layer : mLayers) {
        layer->latchBuffer(); // 获取图形缓冲区
        layer->prepareClientComposition(); // 准备合成
    }
    // 最终合成并显示
    doComposition();
    postFramebuffer(); // 输出到屏幕
}

完整时序图:画展全流程

关键技巧:性能优化秘诀

  1. 减少层级:画展布置不要太复杂(View层级扁平化)
  2. 避免过度绘制:不要在同一区域反复画画
  3. 使用硬件加速:让GPU大神多干活
  4. View复用:像 recyclerView 一样,重复利用画布
java 复制代码
// 优化示例:自定义View避免无效重绘
@Override
protected void onDraw(Canvas canvas) {
    if (needRedraw) { // 只有需要时才重绘
        drawContent(canvas);
        needRedraw = false;
    }
}

总结:一场精密的协作

Android View的绘制就像一场精心组织的画展:

  • ViewRootImpl是总策划,协调整个流程
  • 测量-布局-绘制是核心三部曲
  • Choreographer保证60fps的流畅节奏
  • GPU硬件加速提供强大的绘制能力
  • SurfaceFlinger是最终的舞台总监

理解了这套机制,你就能写出更流畅的UI,成为真正的Android UI大师!

怎么样,同学,现在是不是对View绘制有了更生动的理解?

相关推荐
_祝你今天愉快9 小时前
从驱动来分析服务的添加过程
android
Dovis(誓平步青云)12 小时前
折叠屏悬停看视频,上半屏和下半屏应该各做什么
android·java·服务器·开发语言·安全·音视频
alexhilton13 小时前
让架构边界变成可执行的测试
android·kotlin·android jetpack
hai_android14 小时前
SendChannel 与 ReceiveChannel 通信机制
android
数据治理自习室16 小时前
AI 应用评测体系(GraphRAG)
android·大数据·人工智能·kotlin
爱笑鱼17 小时前
Android 系统启动机制(五):system_server 是 init 启动的,还是 Zygote fork 出来的?
android
智购科技无人售货机工厂18 小时前
2026自动售货机防拆机物理安全设计:从安全螺丝到结构互锁的工程实践~YH
android·网络·驱动开发·python·单片机·安全·云原生
开开心心就好18 小时前
电子教鞭工具支持画框写字插图片功能齐全
android·开发语言·前端·javascript·人工智能·pdf·html
Dovis(誓平步青云)18 小时前
拍视频前先把镜头想清楚:做一个分镜取景辅助器
android·java·服务器·javascript·人工智能
峥嵘life19 小时前
Android16 系统 APEX 模块说明
android·大数据·开发语言