Flutter在线编程实践总结

1.Flutter架构

Flutter的架构主要分成三层:Framework,Engine,Embedder。

1.Framework使用dart实现,包括Material Design风格的Widget,Cupertino(针对iOS)风格的Widgets,文本/图片/按钮等基础Widgets,渲染,动画,手势等。 此部分的核心代码是:flutter仓库下的flutter package,以及sky_engine仓库下的io,async,ui(dart:ui库提供了Flutter框架和引擎之间的接口)等package。

2.Engine使用C++实现,主要包括:Skia,Dart和Text。Skia是开源的二维图形库,提供了适用于多种软硬件平台的通用API。

3.Embedder是一个嵌入层,即把Flutter嵌入到各个平台上去,这里做的主要工作包括渲染Surface设置,线程设置,以及插件等。 从这里可以看出,Flutter的平台相关层很低,平台(如iOS)只是提供一个画布,剩余的所有渲染相关的逻辑都在Flutter内部,这就使得它具有了很好的跨端一致性。
图1

2.Flutter视图绘制

对于开发者来说,使用最多的还是framework,我就从Flutter的入口函数开始一步步往下走,分析一下Flutter视图绘制的原理。

在Flutter应用中,main()函数最简单的实现如下

// 参数app是一个widget,是Flutter应用启动后要展示的第一个Widget。
void runApp(Widget app) {
  WidgetsFlutterBinding.ensureInitialized()
    ..scheduleAttachRootWidget(app)
    ..scheduleWarmUpFrame();
}

1.WidgetsFlutterBinding

WidgetsFlutterBinding继承自BindingBase 并混入了很多Binding,查看这些 Binding的源码可以发现这些Binding中基本都是监听并处理Window对象(包含了当前设备和系统的一些信息以及Flutter Engine的一些回调)的一些事件,然后将这些事件按照Framework的模型包装、抽象然后分发。

WidgetsFlutterBinding正是粘连Flutter engine与上层Framework的“胶水”。

  1. GestureBinding:提供了window.onPointerDataPacket 回调,绑定Framework手势子系统,是Framework事件模型与底层事件的绑定入口。

  2. ServicesBinding:提供了window.onPlatformMessage 回调, 用于绑定平台消息通道(message channel),主要处理原生和Flutter通信。

  3. SchedulerBinding:提供了window.onBeginFrame和window.onDrawFrame回调,监听刷新事件,绑定Framework绘制调度子系统。

  4. PaintingBinding:绑定绘制库,主要用于处理图片缓存。

  5. SemanticsBinding:语义化层与Flutter engine的桥梁,主要是辅助功能的底层支持。

  6. RendererBinding: 提供了window.onMetricsChanged 、window.onTextScaleFactorChanged 等回调。它是渲染树与Flutter engine的桥梁。

  7. WidgetsBinding:提供了window.onLocaleChanged、onBuildScheduled 等回调。它是Flutter widget层与engine的桥梁。

WidgetsFlutterBinding.ensureInitialized()负责初始化一个WidgetsBinding的全局单例,代码如下

class WidgetsFlutterBinding extends BindingBase with GestureBinding, ServicesBinding, SchedulerBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
  static WidgetsBinding ensureInitialized() {
    if (WidgetsBinding.instance == null)
      WidgetsFlutterBinding();
    return WidgetsBinding.instance;
  }
}

看到这个WidgetsFlutterBinding混入(with)很多的Binding,下面先看父类BindingBase:

abstract class BindingBase {
   ...
  ui.SingletonFlutterWindow get window => ui.window;//获取window实例
  @protected
  @mustCallSuper
  void initInstances() {
    assert(!_debugInitialized);
    assert(() {
      _debugInitialized = true;
      return true;
    }());
  }
}

看到有句代码Window get window => ui.window链接宿主操作系统的接口,也就是Flutter framework 链接宿主操作系统的接口。系统中有一个Window实例,可以从window属性来获取,看看源码:

// window的类型是一个FlutterView,FlutterView里面有一个PlatformDispatcher属性
ui.SingletonFlutterWindow get window => ui.window;
// 初始化时把PlatformDispatcher.instance传入,完成初始化
ui.window = SingletonFlutterWindow._(0, PlatformDispatcher.instance);
// SingletonFlutterWindow的类结构
class SingletonFlutterWindow extends FlutterWindow {
  ...
  // 实际上是给platformDispatcher.onBeginFrame赋值
  FrameCallback? get onBeginFrame => platformDispatcher.onBeginFrame;
  set onBeginFrame(FrameCallback? callback) {
    platformDispatcher.onBeginFrame = cal

猜你喜欢

转载自blog.csdn.net/youdaotech/article/details/121249696
今日推荐