Flutter 基础架构、渲染流水线和状态管理

2021-03-24  本文已影响0人  犯迷糊的小羊

为什么需要 Flutter

Flutter 通过自建绘制引擎,具备与 Native 相媲美的性能,同时能够磨平平台开发的差异性。


Flutter 架构

Flutter 架构可分为 Dart APP 层、Flutter 框架层、引擎层(面向操作系统的 C++ 引擎以及面前 Web 的 Web 引擎)、平台嵌入层。

Flutter 框架层

Flutter 框架层实现一套基础库用于处理动画、绘图和手势,在这之上 Rendering 层用于组件的底层渲染的结构数据,Widgets 层面向开发者提供一套描述视图结构的语言,并基于绘图封装了两种风格的 UI 组件库

底层引擎层

引擎层可分为 C++ 引擎和 Web 引擎,其中 C++ 引擎包括 Skia 渲染引擎、Dart 运行时以及文字排版引擎等

设计思想

Widget 是视图的基本单元和配置信息

视图以 Widget 为单位,Widget 的状态描述了页面的状态,状态发生变化,Widget 会重新构建 Widget。

Widget 有以下特点:

最小颗粒度更新渲染树

Flutter 会比对前后状态的变化,以确定底层渲染树从一个状态切换到下一个状态所需要的最小改变。

渲染流水线

Flutter 渲染视图的本质就是在 Vsync 信号中,通过 UI 线程快速的构建并生成抽象的视图结构数据,并将抽象视图结构数据发送给 GPU 线程,GPU 线程将视图结构数据进行光栅化和上屏;

首先从宏观上理解 Flutter 的渲染流水线:

线程模型

理解 Flutter 的渲染流水线,需要先理解 Flutter 的线程模型,Flutter 的四大线程配合来完成渲染 UI 工作:

值得注意的是,Flutter Engine自己不创建管理线程。Flutter Engine线程的创建和管理是由embedder负责的。Embeder指的是将引擎移植到平台的中间层代码。

UI 线程

当用于描述 UI 的 widget 树发生变化,会触发 build 阶段,build 阶段后会进入 layout 阶段生成 RenderObject tree,layout 完后进入 paint 阶段生成绘制指令 layer tree。

build 阶段

Flutter 对视图结构的抽象描述采用了三棵树:widget tree、element tree 和 render tree。可把它们类比成:

widget tree => jsx
element tree => virtual dom
render tree => rendering tree (dom + cssom)

widget tree

widget tree 是 Dart 代码中所写的组件结构,描述 UI 元素的配置信息,widget 是 immutable 的,如果 widget 的状态发生更新,则会进行重建。实际业务场景中, widget 会频繁进行重建;

element tree

element tree 是 widget 的一种抽象,是视图中真正显示的元素,也是连接 widget tree 和 render tree 的桥梁;

当 widget 挂载到 widget tree 的时候,会调用 widget.createElement() 方法,创建其对应的 Element。Flutter 再将这个 Element 挂载到 element tree 并持有创建它的 widget 的引用

当 widget 发生变化时,会将其 element 标记为 dirty element,在下一次更新视图时根据这个状态只更新被修改的内容,从而提升渲染性能;

element 的更新时机是根据 widget 的两个属性进行的:

如果二者都没发生改变,则会复用该 element,并将新的 widget 配置数据更新到 element;

render tree

render tree 是真正进行组件布局渲染的工作,render tree 每个节点都是继承自 RenderObject 类对象,其由 Element 中的 renderObject 或 RenderObjectWidget 的 createRenderObject 方法生成;

布局阶段

UI 线程根据 RenderObject tree 进行布局,具体可分为两个线性过程:从顶部往下传递布局约束,从底部往上传递布局信息:

绘制阶段

UI 线程根据 RenderObject tree 生成绘制指令并形成 layer tree

状态管理

StatefulWidget

Flutter 的 widget 可分为 StatefulWidget 和 StatelessWidget。

StatefulWidget 的生命周期

理解 setState 的更新机制

setState()过程主要工作是记录所有的脏元素,添加到BuildOwner对象的_dirtyElements成员变量,然后调用scheduleFrame来注册Vsync回调。 当下一次vsync信号的到来时会执行handleBeginFrame()和handleDrawFrame()来更新UI。

状态管理机制

widget 间的通信机制


参考资料

Flutter原理:三棵重要的树(渲染过程、布局约束、应用视图的构建等)

硬件绘图原理

Flutter 实战

Flutter 跨平台演进及架构开篇

Flutter UI 绘制原理引导

Flutter WebView 与 JS 通信

Flutter WebView与JS交互简易指南

Dart

上一篇 下一篇

猜你喜欢

热点阅读