熟悉 Flutter 框架工作流程,对 Flutter APP 开发很有帮助。这篇文章不会介入过多源码,而是希望对 Flutter 框架有大体比较清晰的认识。
1. 入口
Flutter APP 的入口,一般就是我们的 main 函数。二般情况下,需要我们通过在 Android(或其它平台),配置 flutterEngine 时,指定入口函数名 entryPointName。同时最好在 Flutter 端,用注解 @pragma(vm:entry-point) 进行标识。
进入 main 方法,我们一般会执行 runApp 方法。如果需要全局捕获异常,我们可以使用 Zone 类相关 API。runApp 方法做了什么?
1. 初始化 bindings
Flutter 中的 bindings 是对 window 对象功能细分和具体实现。Window 是 Flutter 框架为我们提供的,抽象的,最基本的用户接口(user interface)。
bindings 对象有 7 种:
GestureBinding:手势绑定,负责用户触摸点击滑动等屏幕相关操作。
SchdulerBinding:调度绑定,负责 Flutter 框架运行的流程驱动。
ServicesBinding:服务绑定,负责 Flutter 框架与 native 平台数据通信。
PaintingBinding:绘制绑定,负责管理图像内存处理。
SemanticsBinding:语义化绑定,负责 APP 语义化功能实现。
RenderingBinding:渲染绑定,负责 Flutter 框架页面渲染相关内容。
WidgetsBinding:组件绑定,负责 Flutter 框架 Widget 树构建相关操作。
2. 构建三棵树
从第一个 Widget( RenderObjectToWidgetAdapter )为起点,以 Element (第一个为 RenderObjectToWidgetElement)为主线,构建 Widget、Element、RenderObject 三颗树。
这一过程就是 Flutter 框架的 build 构建过程。
3. 主动驱动 Flutter 框架运行
runApp 方法内部通过调用 SchdulerBinding 的 ScheduleWarmUpFrame 方法,主动驱动 Flutter 框架运行。ScheduleWarmUpFrame 主要调用两个方法,handleBeginFrame,handleDrawFrame
handleBeginFrame
handleBeginFrame 阶段,执行通过 scheduleFrameCallback(SchedulerBinding)注册的 transient frame callbacks,每帧动画计算过程就在这里回调执行。
在 handleBeginFrame 执行结束后,会调度执行 microtasks。这里涉及到 Flutter 框架单线程模型如何实现异步操作?
handleDrawFrame
handleDrawFrame 驱动渲染管道 rendering pipeline 生成一帧。其中 drawFrame 包括以下阶段:
1. The layout phase:布局阶段,重新布局标记为 dirty 的 RenderObject。
2. The compositing bits phase:合成二进制阶段,重新合成标记为 dirty 的 RenderObject 的二进制数据。
3. The paint phase:绘制阶段,生成 Layer tree,重绘 RenderObject。
4. The compositing phase:组合阶段,组合 Layer tree 为 Scene,发送个 GPU 渲染。
5. The semantics phase:语义化阶段,更新标记为 dirty 的 RenderObject 对应的 semanticNode 节点,重新生成语义化树。
6. The finalization pahse:调用 post-frame callbacks。
2. 起点
这里所说的起点和下边的终点是指,Flutter Engine 是从哪里进入 Flutter Framework 执行流程,又是从哪里开始接替 Flutter Framework 工作的。
Flutter 是一个渲染框架,涉及屏幕渲染,一个必提的概念那得是 vsync 信号。Flutter 为我们提供了调度一个 vsync 信号的 API,和当 vsync 信号到来时需要触发的回调。这些方法封装在了 Window 对象里。
scheduleFrame
framework 向 engine 发出请求,希望在下一次合适(vsync 信号到来)的时候通知自己。
onBeginFrame
vsync 到来时,engine 通知 framework 开始准备提供一帧(scene)。这是 engine 进入 framework 的第一个回调方法。
onDrawFrame
onBeginFrame 执行后,engine 会处理 microtasks,之后调用 onDrawFrame 通知 framework 执行渲染帧的第二阶段。
这两个方法具体实现就是上边 SchedulerBinding 对应的 handleBeginFrame 和 handleDrawFrame。
3. 终点
Flutter framework 渲染流程执行结束后,会由 Layer 通过 SceneBuilder 生成 Scene 对象,然后交由 window 去通知 engine 做渲染。
最后,flutter framework 的终点就是 window 的 render 方法,将生成的 scene 对象由 engine 交由 GPU 去做渲染。