Android刷新与绘制机制详解 笔记

一、刷新机制(VSYNC与双缓冲/三缓冲)

1. VSYNC信号

  • 作用:垂直同步信号,屏幕刷新周期(通常60Hz = 16.67ms)

  • 类型

    • HW-VSYNC:硬件产生
    • SW-VSYNC:软件模拟

2. 双缓冲机制

java

arduino 复制代码
// 传统双缓冲问题
帧1:CPU计算 → GPU渲染 → 显示
帧2:CPU计算 → GPU渲染 → 显示
// 如果渲染超过16.67ms,会掉帧

3. Project Butter引入的改进

  • VSYNC同步:所有绘制与VSYNC对齐
  • 三缓冲:增加一个缓冲区减少等待
arduino 复制代码
// 三缓冲流程
VSYNC 1:CPU计算帧1 → GPU渲染帧1
VSYNC 2:CPU计算帧2 → GPU渲染帧2
VSYNC 3:CPU计算帧3 → GPU渲染帧3
// 同时GPU可以并行处理不同帧

二、绘制机制(View绘制流程)

1. 绘制三大步骤

java

scss 复制代码
// ViewRootImpl.performTraversals()触发
1. Measure (测量)
2. Layout (布局)
3. Draw (绘制)

2. Measure过程

java

arduino 复制代码
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // 1. 根据父容器的MeasureSpec和自身LayoutParams计算
    // 2. 测量子View
    // 3. 设置最终尺寸setMeasuredDimension()
}

MeasureSpec组成

  • 高2位:测量模式

    • UNSPECIFIED:父容器不限制
    • EXACTLY:精确值(match_parent或具体数值)
    • AT_MOST:最大不超过(wrap_content)
  • 低30位:测量值

3. Layout过程

java

arduino 复制代码
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    // 确定View自身位置
    // 确定子View位置(如果是ViewGroup)
}

4. Draw过程

java

typescript 复制代码
public void draw(Canvas canvas) {
    // 绘制顺序:
    // 1. 绘制背景 (drawBackground)
    // 2. 如果需要,保存图层
    // 3. 绘制内容 (onDraw)
    // 4. 绘制子View (dispatchDraw)
    // 5. 绘制装饰(滚动条等)
    // 6. 绘制前景
}

三、Choreographer核心调度器

1. 主要作用

java

arduino 复制代码
// 协调VSYNC与绘制流程
public final class Choreographer {
    // 三种回调类型
    public static final int CALLBACK_INPUT = 0;
    public static final int CALLBACK_ANIMATION = 1;
    public static final int CALLBACK_TRAVERSAL = 2; // 绘制回调
    
    // 注册VSYNC回调
    public void postFrameCallback(FrameCallback callback);
}

2. 绘制调用链

scss 复制代码
Choreographer.postFrameCallback()
    ↓
VSYNC信号到来
    ↓
Choreographer.doFrame()
    ↓
ViewRootImpl.performTraversals()
    ↓
View.measure() → View.layout() → View.draw()

四、硬件加速 vs 软件绘制

1. 软件绘制

  • Canvas:Skia 2D图形库
  • DisplayList:无,直接绘制
  • 渲染:CPU完成

2. 硬件加速(Android 3.0+)

java

ini 复制代码
// 开启硬件加速
android:hardwareAccelerated="true"

硬件加速流程

text

scss 复制代码
View.draw() → 生成DisplayList → 上传GPU → GPU渲染

优势

  • GPU并行处理
  • 支持属性动画优化
  • DisplayList重用

五、完整绘制流程时序

六、性能优化关键点

1. 减少绘制范围

java

scss 复制代码
// 使用setWillNotDraw(true)跳过不必要的绘制
if (背景透明 && 没有覆盖onDraw) {
    setWillNotDraw(true);
}

2. 避免过度绘制

xml

xml 复制代码
<!-- 开启调试 -->
<!-- 1. 蓝色:绘制1次 -->
<!-- 2. 绿色:绘制2次 -->
<!-- 3. 淡红:绘制3次 -->
<!-- 4. 深红:绘制4次+ -->

3. 使用RenderThread(Android 5.0+)

java

arduino 复制代码
// UI线程:生成DisplayList
// RenderThread:上传GPU,执行渲染

4. 优化建议

  • 减少View层级:使用ConstraintLayout
  • 避免频繁requestLayout()
  • 使用ViewStub延迟加载
  • 复用ConvertView
  • 关闭不需要的硬件加速

七、总结

Android刷新绘制机制的核心是:

  1. VSYNC同步确保流畅性
  2. Choreographer协调调度
  3. Measure-Layout-Draw三步绘制
  4. 硬件加速提升性能

理解这套机制有助于:

  • 避免卡顿和掉帧
  • 优化应用性能
  • 实现流畅的动画效果
  • 正确使用各种UI组件
相关推荐
2601_949575868 小时前
Flutter for OpenHarmony二手物品置换App实战 - 商品卡片实现
android·flutter
2601_9495758610 小时前
Flutter for OpenHarmony二手物品置换App实战 - 表单验证实现
android·java·flutter
龚礼鹏12 小时前
图像显示框架八——BufferQueue与BLASTBufferQueue(基于android 15源码分析)
android·c语言
1登峰造极13 小时前
uniapp 运行安卓报错reportJSException >>>> exception function:createInstanceContext, exception:white screen
android·java·uni-app
木易 士心13 小时前
Android Handler 机制原理详解
android
kkk_皮蛋13 小时前
作为一个学生,如何用免费 AI 工具手搓了一款 Android AI 日记 App
android·人工智能
金山毒霸电脑医生13 小时前
植物大战僵尸杂交版最新v0.2版下载安装|2025图文解析教程
android·游戏·ios·植物大战僵尸·软件下载安装
羑悻的小杀马特13 小时前
Docker-Android 容器化 + cpolar 穿透,完善异地调试
android·运维·docker·容器·cpolar
恋猫de小郭13 小时前
Android Gradle Plugin 9.0 发布,为什么这会是个史诗级大坑版本
android·flutter·ios·开源
Calebbbbb15 小时前
Ubuntu 24.04 + Android 15 (AOSP) 环境搭建与源码同步完整指南
android·linux·ubuntu