一.Flutter架构构成
Flutter的架构是一个可扩展的分层系统设计,上层组件各自依赖下层组件,层级不可越级访问,各个层级模块可替换
Flutter从分层构成看主要分为3个层级:
1 | Dart Framework |
- 从官网的架构图片层级分析:(科学上网可见图片)
1. Platform Embedder:(平台嵌入层)
- 平台层潜入层作用:是把 Flutter 代码打包嵌入到具体的实现平台, 来呈现所有 Flutter 内容的原生系统应用, 它充当着宿主操作系统(android/ios/macOS/..)和 Flutter 之间的粘合剂的角色。
- 提供flutter的运行入口,初始化 Flutter 引擎,管理flutter应用生命周期
- 并对上层提供最基础的能力(渲染画布、插件系统、交互管理、消息循环等)
2. C/C++ Engine:
- 它的主要职责是光栅化合成上屏幕用于显示绘制内容(当需要绘制新一帧的内容时,将负责对需要合成的场景进行栅格化)
- 提供了 Flutter 核心 API 的底层实现,包括图形(通过 Skia)、文本布局、文件及网络 IO、辅助功能支持、插件架构和 Dart 运行环境及编译环境的工具链。
- 引擎将底层 C++ 代码包装成 Dart 代码,通过 dart:ui 暴露给 Flutter 框架层,而dart:ui 包是 Flutter App 的构建基础
3. Dart Framework:
- 提供了以 Dart 语言编写的现代响应式框架,对渲染逻辑做了统一封装,屏蔽了底层实现,对底层 C++ Engine 提供双向通信能力
- 开发者只需要通过该层使用widget控件构建 App 视图即可
- Dart Framework 包括丰富的平台,布局和基础库。从上层到下层,依次有:
1 | Material 和 Cupertino 分别实现了 android Material 和 iOS 设计规范。 |
Flutter核心组件
1.Widget (应用开发者直接使用)
- Widget是Flutter的核心部分, Flutter的口号 Everything’s a widget,是构建应用的基础块
- Widgets 通过布局组合形成一种层次结构关系。每个 Widget 都嵌套在其父级的内部,并可以通过父级接收上下文
- Widget 不只表示UI 控件,还表示一些功能性的组件Navigator、GestureDetector 组件
2. Element (实例化的 Widget 对象)
- 在构建的阶段,Flutter 会将代码中描述的 widgets 转换成对应的 Element 树,每一个 Widget 都有一个对应的 Element。每一个 Element 代表了树状层级结构中特定位置的 widget 实例。
- 目前有两种 Element 的基本类型:
1 | ComponentElement : Element 的宿主 |
- 在代码阶段的widget层级在生成绘制后会多一些层级(源码和官网演示看查看到),这里面多一些的层级往往就是参与布局和绘制RenderObjectElement
- 注:ColoredBox 、RawImage、RichText 为绘制时产生的新增widget层级(科学上网可见图片)
3.RenderObject(树形)
- 用于应用界面的布局和绘制,保存了元素的大小,布局等信息
- 在构建阶段,Flutter 会为 Element 树中的每个 RenderObjectElement 创建或更新其对应的一个从 RenderObject 继承的对象。
- 当应用运行时 Flutter 使用 RenderObject 的数据绘制应用界面,最终形成一个 Render Tree。(图片需要科学上网)
- 大部分的 Flutter widget 是由一个继承了 RenderBox 的子类的对象渲染的,真正负责干活(layout、paint)
- 所有 RenderObject 的根节点是 RenderView,代表了渲染树的总体输出。当平台需要渲染新的一帧内容时(例如一个 vsync 信号或者一个纹理的更新完成),会调用一次 compositeFrame() 方法,它是 RenderView 的一部分。该方法会创建一个 SceneBuilder 来触发当前画面的更新。当画面更新完毕,RenderView 会将合成的画面传递给 dart:ui 中的 Window.render() 方法,控制 GPU 进行渲染。
三者直接关系:
1 | Widget 是应用界面的声明的控件,为开发者直接使用的控件 |
- Widget重新创建,Element 树和 RenderObject 树并不会完全重新创建,如果 newWidget 与oldWidget 的 runtimeType 和 key 相等时,更新已经存在的 Element 对象,不然就选择重新创建新的 Element。
二.Flutter渲染原理
- 从Flutter的核心控件大概已经初步了解到了渲染的相关流程,核心控件到绘制的情况。
- 一般计算机绘图原理:屏幕显示器一般以60Hz的固定频率刷新,每一帧图像绘制完成后,会继续绘制下一帧,这时显示器就会发出一个Vsync信号,按60Hz计算,屏幕每秒会发出60次这样的信号。CPU计算好显示内容提交给GPU,GPU渲染好传递给显示器显示。flutter 渲染原理相同。渲染过程会使用上边介绍的核心流程控件。
- Flutter 的渲染流水线也包括两个线程,UI 线程和 GPU 线程,UI 线程主要负责的是根据 UI 界面的描述生成 UI 界面的绘制指令,建立过程中生成 Render,往下布局、绘制大小等工作,完成以后会生成一个 Layer Tree,到了 GPU 线程之后会调用 Skia 做渲染