Android 14 HWUI 源码研究 View Canvas RenderThread ViewRootImpl skia

HWUI 整体架构

HWUI主要功能是完成应用程序可视化元素绘制,核心代码位于framework c++层,承接Java层View绘制信息,开启进程唯一的渲染线程,借用skia绘制能力,完成渲染。

整体模块流程

Application-Activity-HWUI层级关系

注意:一个进程对应唯一的渲染线程,UI线程和渲染线程有个同步操作。

HWUI核心类和层级关系

容易混淆的Canvas关系

理解的核心:Canvas用来收集View的绘制信息,为了解耦才搞得这么多名字。

Canvas层级和对应关系

Java层两类Canvas:RecordingCanvas和Canvas。

  • RecordingCanvas直接对应C++层SkiaRecordingCanvas,SkiaRecordingCanvas实际使用RecordingCanvas记录指令
  • Canvas直接对应C++层SkiaCanvas,SkiaCanvas直接引用SkCanvas。
  • RecordingCanvas纯做指令记录

重要对象创建入口:

最左侧给出源码层面各主要对象调用入口。

()表示构造函数里创建右侧对象。

xx()表示正常函数里调用创建右侧对象。

其它:

RecordingCanvas负责指令记录动作,RenderNode 负责保存指令记录结果和渲染属性。

RenderProxy RenderThread CanvasContext IRenderPipeline负责指令渲染

全局大循环

协作关系:

细节待补充:Activity PhoneWindow WindowManagerGlobal DecorView ViewRootImpl

Window和View体系区别:

DecorView是View根节点,activity setContentView是DecorView子节点

ViewRootImpl衔接Window和View,并且负责View更新、渲染。

View相关的几大流程:

new Activity() -> attach() -> new PhoneWindow()待补充细化,对应"开始1 "

addView把View添加到渲染线程,待补充细节,对应"开始2"

performTranversals()

全局刷新流程,包含measure layout draw复杂子流程

performDraw()

触发指令记录和指令渲染流程

* beginRecording 创建Java::RecordingCanvas和C++::SkiaRecordingCanvas * updateRootDisplayList() 触发指令录制动作,用RecordingCanvas完成View到DisplayList转换 * endRecording() 把SkiaRecordingCanvas记录的指令,统一转存到RenderNode里

* syncAndDrawFrame() 指令线程同步和渲染。涉及到C++层RenderProxy RenderThread DrawFrameTask CanvasContext重要对象

渲染线程创建流程和核心对象

RenderProxy衔接Java层信息

RenderThread进程唯一的渲染线程

DrawFrameTask一帧绘制逻辑

CanvasContext负责一帧具体的绘制

指令记录流程

核心是把View的属性和绘制信息,通过C++层RecordingCanvas记录到DisplayList中

指令同步流程

指令渲染流程

Surface -> ANativeWindow -> EGLSurface画布创建流程

  • 初始化入口在ViewRootImpl.performTraversals()大函数里
  • 为什么用ReliableSurface封装一下,没深入研究
  • EGL和Skia环境创建主要在RenderThread.requireGlContext()函数
  • 从源码分析,一共三个地方地方调用requireGlContext()

View树和RenderNode树

类协作关系

协作

  • 一个Application进程,对应多个Activity,一个Activity一一对应PhoneWindow
  • PhoneWindow唯一持有一个DecorView
  • DecorView一一对应ViewRootImpl
  • ViewRootImpl创建并持有ThreadedRender
  • ThreadedRender与C++层RenderProxy一一对应
  • RenderProxy负责渲染代理,持有三个重要对象RenderThread、CanvasContext、DrawFrameTask
  • RenderThread是渲染线程,是单态模式,进程唯一
  • Activity.setContentView() -> PhoneWindow.setContentView(),把View挂到DecorView子节点上。
  • WindowManagerImpl.addView()设置给ViewRootImpl,并与ThreadedRender模块对接

RenderNode

  • 用于保存渲染属性和渲染指令
  • mStagingProperties和mStagingDisplayList只在MainThread修改
  • mProperties和mDisplayList只在RenderThread使用
  • 数据同步发生在DrawFrameTask的run()函数,详见"指令同步"小节

其它:

PhoneWindow DialogWindow SubMenuWindow ---> Window

PhoneWindow是Activity和View交互中间层,帮助Activity管理View

RenderPipeline模块

执行渲染模块相对结构清晰,重点关注:

  • makeCurrent()
  • draw()
  • swapBuffers()

Native Canvas关系

  • SkiaRecordingCanvas起到桥接作用,对上接收Java api调用
  • RecordingCanvas完成Op记录
  • DisplayListData真正存储Op的地方

skia核心资源三个使用场景

相关推荐
峥嵘life34 分钟前
Android 蓝牙设备连接广播详解-2026
android·python·学习
MusingByte3 小时前
别再裸用 Claude Code 了!安卓开发者必装 13 个官方推荐插件,效率翻 3 倍省 70% token
android
_李小白4 小时前
【android opencv学习笔记】Day 29: 滤波算法之Sobel 边缘检测
android·opencv·学习
Dxy12393102164 小时前
Python 操作 MySQL 事务:从入门到避坑
android·python·mysql
峥嵘life6 小时前
Android getprop 属性限制详解:User 版本属性获取问题分析
android·开发语言·python·学习
一航jason7 小时前
Speed Tools:一套低侵入的 Android 插件化 + 动态换肤 + 字体切换框架
android·插件化·组件化·换肤
李斯维8 小时前
Jetpack 可观察数据容器 LiveData 的入门与基础使用
android·android jetpack
问心无愧05138 小时前
ctf show web入门261
android·前端·笔记
alexhilton9 小时前
车载系统中的可扩展UI:从UI嵌入到系统窗口编排
android·kotlin·android jetpack
Cloud_Shy6189 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第一章 Item 4 - 6)
android·数据库·论文阅读·python