【Flutter】宏观一瞥

Flutter 作为一个优秀的跨平台UI库,跨平台的宿主包含 iOS 、Android、Web。那Flutter 是如何配合线程,完成UI绘制渲染,事件响应等。

1、引入

dart 代码是在哪个线程工作,组件是如何绘制渲染的,事件是如何响应的。带着上述的问题,我将从宏观的角度来研究一下Flutter,

Flutter 使用多个线程来完成其工作,但叠加层中只显示了其中两个线程。所有 Dart 代码都在 UI 线程上运行。尽管您无法直接访问任何其他线程,但您在 UI 线程上的操作会对其他线程产生性能影响。

  • 平台线程(宿主程序的主线程,iOS & Android的主线程)

  • UI线程
    UI线程在Dart VM中执行Dart代码。该线程包含您编写的代码以及 Flutter 框架代表您的应用程序执行的代码。当您的应用程序创建并显示场景时,UI 线程会创建一个图层树(一个包含与设备无关的绘画命令的轻量级对象),并将图层树发送到光栅线程以在设备上渲染。不要阻塞此线程! 显示在性能叠加层的底行中。

  • 光栅线程(以前的GPU线程)
    光栅线程获取图层树并通过与 GPU(图形处理单元)通信来显示它。您无法直接访问光栅线程或其数据,但是,如果该线程速度缓慢,则可能是您在 Dart 代码中执行某些操作的结果。Skia 和 Impeller 图形库在该线程上运行。显示在性能叠加层的顶行中。该线程以前称为“GPU 线程”,因为它针对 GPU 进行光栅化。但它是在CPU上运行的。我们将其重命名为“光栅线程”,因为许多开发人员错误地(但可以理解)假设线程在 GPU 单元上运行。

  • I/O线程
    执行昂贵的任务(主要是 I/O),否则会阻塞 UI 或光栅线程。该线程未显示在性能覆盖图中。

1.1 Flutter架构布局

【Flutter】宏观一瞥_第1张图片

1.2 Widget

Flutter中一切接组件,关于 dart.FrameWork 中涉及的五层框架,Materia, Cupertino 是对低层widget的抽象,关于lv1层库中的组件比较常见的floatedButton, Scaffold, TextField、Activity等使用的的比较多。

1.3 Rendering

关于Flutter渲染树:这里着重涉及到RenderObject,Flutter Widget 组件库通过使用RenderObject 的层级,来实现布局和后台绘制。一般来说,虽然您可以RenderBox在应用程序中使用自定义类来实现特定效果,但大多数时候您与RenderObject层次结构的唯一交互是调试布局问题。
上述引用源于此处

匆匆一瞥,有些难以理解。我们打开dart.framework 来一探究竟。目录flutter/lib/src/rendering, 我们找到box.dart

引用说明的RenderBox 自定义可在此处注视中说明

// Examples can assume:
// abstract class RenderBar extends RenderBox { }
// late RenderBox firstChild;
// void markNeedsLayout() { }

RenderBox的定义片段

abstract class RenderBox extends RenderObject {
  double _computeIntrinsicDimension(_IntrinsicDimension dimension, double argument, double Function(double argument) computer) {
  }
  ...
}

自造
关于RenderBox 比较底层的Widget,RenderBox实现了布局算法(提供了BoxConstraint). RenderBox 的事件传递,是通过实现HitTest方法的。关于事件的传递,可以参考1301的注释。

1.4 Animation Painting Gesture

此处是绘制 手势 动画和引擎通信的低层API此处,暂不展开。

1.5 Foundation

2、你好、计数器

我们使用flutter create , 创建了一个计数器项目。既然Flutter是一个UI框架,上述又唠了很多关于RenderObject的事情,不眠有些疑惑,flutter 到底是如何布局的,RenderObject是怎么连接到Widget的,那说了500遍的三棵树有何关系。

2.1 关于计数器Widget

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

事例中涉及到了Scaffold, AppBar, Center, Column, floatingActionButton , Text, IconWidget, runApp后到底发生了什么。

2.2 WidgetTree、ElementTree、RenderObjectTree

flutter 作为一个声明式的UI框架,我们创建的Widget 是对组件结构的描述,我们看到的Text Widget和原生中的UILabel 是不一样的,这里通过修改flutter 的状态,来修改Text的值。这里暂且不讲状态,所以就来到我们这边的第一个知识点,WidgetTree。那么Widget树中的节点,Widget 又做了什么呢,

TODO:三棵树

你可能感兴趣的:(Flutter,flutter)