首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

一文带你吃透Android View绘制流程与原理详解

  • 25-04-16 14:40
  • 2618
  • 11729
juejin.cn

Android 中 View 的绘制流程是 UI 框架的核心机制,主要分为 Measure(测量)、Layout(布局)、Draw(绘制)  三个阶段。以下是详细的流程和实现原理分析:

一、绘制流程总览

View 的绘制流程由 ViewRootImpl(Android 3.0+)触发,通过 performTraversals() 方法协调以下三个阶段:

java
代码解读
复制代码
// ViewRootImpl.java private void performTraversals() { performMeasure(); // 测量 performLayout(); // 布局 performDraw(); // 绘制 }

二、Measure 阶段:确定 View 的尺寸

1. 核心方法

  • measure(int widthMeasureSpec, int heightMeasureSpec)
    由父 View 调用,触发子 View 的测量逻辑。
  • onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    自定义 View 需重写此方法,确定自身尺寸。

2. MeasureSpec

  • 组成:32位 int 值,高 2 位表示 Mode(测量模式),低 30 位表示 Size。

  • 三种模式:

    • EXACTLY:精确尺寸(如 match_parent 或具体数值)。
    • AT_MOST:最大尺寸(如 wrap_content)。
    • UNSPECIFIED:未指定(如 ScrollView 的子 View)。

3. 流程细节

  • 父 View 通过 measureChild() 计算子 View 的 MeasureSpec。
  • ViewGroup 需递归测量所有子 View(如 LinearLayout 根据方向计算子 View 尺寸)。
  • 最终通过 setMeasuredDimension() 保存测量结果。

关键问题:

  • wrap_content 为何需要特殊处理?
    默认 onMeasure 不会处理 AT_MOST 模式,需要开发者手动设置尺寸。

三、Layout 阶段:确定 View 的位置

1. 核心方法

  • layout(int l, int t, int r, int b)
    由父 View 调用,确定子 View 的位置。
  • onLayout(boolean changed, int l, int t, int r, int b)
    ViewGroup 需重写此方法,排列子 View(如 FrameLayout 默认堆叠子 View)。

2. 流程细节

  • 父 View 根据子 View 的测量结果,计算其左上右下坐标。
  • 调用子 View 的 layout() 方法,触发其 onLayout()(仅 ViewGroup 需要实现)。
  • 保存位置信息到 mLeft, mTop, mRight, mBottom。

常见场景:

  • RelativeLayout 需要两次测量(依赖关系复杂)。
  • 自定义 ViewGroup 需手动计算子 View 位置。

四、Draw 阶段:绘制内容

1. 核心方法

  • draw(Canvas canvas)
    总控绘制流程,内部调用以下步骤:
    1. 绘制背景:drawBackground()
    2. 绘制自身内容:onDraw(Canvas canvas)
    3. 绘制子 View:dispatchDraw(Canvas canvas)
    4. 绘制装饰(如滚动条) :onDrawForeground()

2. 关键点

  • onDraw() :自定义 View 在此绘制内容(如文本、图形)。
  • dispatchDraw() :ViewGroup 通过此方法分发绘制到子 View。
  • 硬件加速:Android 4.0+ 默认开启,使用 GPU 优化绘制(需注意 API 兼容性)。

优化技巧:

  • 避免在 onDraw() 中创建对象(频繁调用导致 GC)。
  • 使用 Canvas.clipRect() 减少过度绘制。

五、实现原理与底层机制

1. ViewRootImpl 与 Choreographer

  • ViewRootImpl:连接 WindowManager 和 DecorView 的桥梁,通过 performTraversals() 触发绘制。

  • Choreographer:协调 VSYNC 信号(垂直同步),确保绘制按帧率(如 60Hz)执行。

    • 收到 VSYNC 后,通过 Handler 触发 doFrame(),进而执行 performTraversals()。

2. 消息循环机制

  • UI 线程通过 Handler 处理 MessageQueue 中的绘制任务。
  • invalidate() 和 requestLayout() 会向队列插入任务,触发重绘。

3. 双缓冲与 SurfaceFlinger

  • 双缓冲:Surface 包含一个 Front Buffer(显示)和一个 Back Buffer(绘制),减少画面撕裂。
  • SurfaceFlinger:合成多个 Surface 的内容,提交给 Display 显示。

六、常见问题与优化

1. 性能瓶颈

  • 布局嵌套过深:导致多次 Measure/Layout(可用 ConstraintLayout 优化)。
  • 过度绘制:可通过开发者选项中的  "Show GPU Overdraw"  检测。

2. 离线绘制

  • 场景:复杂静态内容(如图表)。
  • 方案:使用 Bitmap 或 Canvas 预渲染,直接绘制缓存。

3. 强制重绘方法

  • invalidate() :请求重绘(主线程调用)。
  • postInvalidate() :非 UI 线程调用重绘。
  • requestLayout() :触发重新测量和布局。

常用方法:

方法作用触发流程
invalidate()标记脏区域,触发重绘(Draw 阶段)只走 draw() 流程
requestLayout()强制重新测量和布局(可能重绘)触发 measure() → layout() → draw()

七、自定义 View 的关键点

  1. 重写 onMeasure() :正确处理 wrap_content。
  2. 避免在 onDraw() 中分配内存:防止卡顿。
  3. 支持 padding 和 margin:在测量和绘制时需考虑。

总结

View 的绘制流程是一个递归的树形遍历过程,通过 Measure → Layout → Draw 确定每个 View 的尺寸、位置和内容。理解其底层机制(如 VSYNC、双缓冲)和优化手段,是开发高性能 UI 的关键。

更多分享

  1. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  2. 一文带你吃透Kotlin协程的launch()和async()的区别
  3. 一文带你吃透HolderFragment 实现ViewModel的生命周期穿透!
  4. 一文带你吃透Android中常见的高效数据结构
  5. 一文带你吃透Android中Service的种类和启动方式
注:本文转载自juejin.cn的QING618的文章"https://juejin.cn/post/7480464724094697509"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top