Flutter runApp 做了些什么

21 min read

Fluttermain 方法完成了前期的准备,三棵树的根节点的生成和绑定,发起预热帧三项任务

入口方法

void main() {
  runApp(MyApp());
}

runApp方法

void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized() // 第一处
    ..scheduleAttachRootWidget(app) //第二处
    ..scheduleWarmUpFrame(); //第三处
}

第一件事 WidgetsFlutterBinding 初始化

class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {

  static WidgetsBinding ensureInitialized() {
    if (WidgetsBinding.instance == null)
      WidgetsFlutterBinding();
    return WidgetsBinding.instance!;
  }
}

ensureInitialized 确保初始化,就是一个确保单例的过程。

第一次执行 ensureInitialized 方法的时候,会走 BindingBase 及其子类的构造方法完成初始化,

确保 Flutter 项目完成初始化并只完成一次。

每一个 Binding 完成的初始化内容如下:

Binding 名 作用
BindingBase 初始化基类,规定了初始化的框架。initInstances 中完成初始化,比如单例等initServiceExtensions 完成服务注册初始化
GestureBinding 初始化手势识别 和 手势追踪框架
SchedulerBinding 初始化 帧调用任务
ServicesBinding 初始化 插件通道、系统的插件。
PaintingBinding 初始化 图片缓存
SemanticsBinding 初始化 语义框架
RendererBinding 初始化 渲染机制 和 根 RenderObject
WidgetsBinding 初始化 Element 机制 和 Debug 显示机制

第二件事 绑定根 Widget

void scheduleAttachRootWidget(Widget rootWidget) {
  Timer.run(() {
    attachRootWidget(rootWidget);
  });
}
void attachRootWidget(Widget rootWidget) {
  final bool isBootstrapFrame = renderViewElement == null;
  _readyToProduceFrames = true;
  _renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
    container: renderView,
    debugShortDescription: '[root]',
    child: rootWidget,
  ).attachToRenderTree(buildOwner!, renderViewElement as RenderObjectToWidgetElement<RenderBox>?);
  if (isBootstrapFrame) {
    SchedulerBinding.instance!.ensureVisualUpdate();
  }
}

第三件事 预热帧

我们知道屏幕的显示是根据 Vsync 信号的.每次收到 Vsync 之后,会进行一系列的计算等,然后显示出来。scheduleWarmUpFrame 的作用就是不用等待下次的 Vsync,而是直接发起绘制。