Flutter渲染完全解读系列:启动与三棵树的构建

本文深入解析Flutter启动过程,涉及调用图、初始化Binding、渲染树与Widget树的构建、RenderObject树构建。通过分析关键方法如runApp、attachRootWidget、mount等,揭示Flutter如何构建三棵树并完成渲染。同时,文章提供了Flutter学习大纲和资源链接,适合移动开发人员深入理解Flutter工作原理。
摘要由CSDN通过智能技术生成

现在,flutter这门技术已经算是逐渐走向成熟,大大小小的互联网公司不少都开始投入使用。还没有上手的移动开发们可以放心上手了,毕竟好不好用,也只有用了才知道。

学习一门知识最好的办法就是学以致用,并总结出自己的方法论。也只有真正理解了,才能总结出有用的经验。下面是知乎一个大佬的学习经验分享,欢迎大家一起探讨学习。

大佬原文地址:https://zhuanlan.zhihu.com/p/388724188

调用图

我们用下面的例子来分析Flutter启动所做的事情

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

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

初始化Binding

runApp

void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized()
    ..scheduleAttachRootWidget(app)
    ..scheduleWarmUpFrame();
}

runApp中,我们会调用WidgetsFlutterBinding.ensureInitialized()来初始化Binding

Binding

Binding是一系列单例,在启动的时候初始化,其中包括了WidgetsFlutterBindingBindingBaseGestureBindingSchedulerBindingServicesBinding等,下面来分析它们的作用

  • BindingBase: 是所有类的基类,负责初始化其它类、初始化一些Native相关的信息(如平台是Android还是iOS)、注册基本的Native事件(如热更新、退出)
  • GestureBinding: 提供window.onPointerDataPacket回调,接受Native事件,负责事件转换及分发
  • SchedulerBinding: 使用了window.scheduleFrame来通知Native及使用window.onBeginFramewindow.onDrawFrame回调来接收消息,主要是负责通知Native在下一侦的事件下发与事件注册,当我们调用setState后,就会触发此类的方法,等待事件下发后进行渲染
  • ServicesBinding: 使用window.onPlatformMessage回调,负责通道相关的初始化及通信相关的处理
  • PaintingBinding: 与绘制相关的函数绑定,还处理一些图片渲染相关的缓存
  • SemanticsBinding: 注册平台相关的辅助函数
  • RendererBinding: 初始化PipelineOwnerrenderViewonMetricsChangedonTextScaleFactorChangedonPlatformBrightnessChangedonSemanticsEnabledChanged onSemanticsAction等,用于监听并处理平台渲染相关如字体、状态栏改变时的事件,是渲染输与Flutter engine沟通的桥梁
  • WidgetsBinding: 初始化BuildOwner,注册window.onLocaleChangedonBuildScheduled等回调。它是Flutter widget层与engine的桥梁。

渲染树的构建

attachRootWidget

[-> packages/flutter/lib/src/widgets/binding.dart]

void attachRootWidget(Widget rootWidget) {
  _readyToProduceFrames = true;
  _renderViewElement = RenderObjectToWidgetAdapter<RenderBox>(
    container: renderView,
    debugShortDescription: '[root]',
    child: rootWidget,
  ).attachToRenderTree(buildOwner!, renderViewElement as RenderObjectToWidgetElement<RenderBox>?);
}

上面会先初始化一个RenderObjectToWidgetAdapter,它是一个特殊的Widget,主要用Flutter树根节点的初始化,其中传了一个renderView,上面提到了是在RendererBinding初始化时就已经初始化了,它是根RenderObject节点,rootWidget就是我们runApp时传入的Widget

后面调用了attachToRenderTree会开始一系列的树构建

attachToRenderTree

[-> packages/flutter/lib/src/widgets/binding.dart]

RenderObjectToWidgetElement<T> attachToRenderTree(BuildOwner owner, [ RenderObjectToWidgetElement<T>? element ]) {
  // 如果element==null执行,第一次渲染element一定为null
  if (element == null) {
    owner.lockState(() {
      // 调用createElement创建Element
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值