行业知识
【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架构布局
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; @override State createState() => _MyHomePageState();}class _MyHomePageState extends State { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override 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: [ 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, Icon等Widget, runApp后到底发生了什么。
2.2 WidgetTree、ElementTree、RenderObjectTree
flutter 作为一个声明式的UI框架,我们创建的Widget 是对组件结构的描述,我们看到的Text Widget和原生中的UILabel 是不一样的,这里通过修改flutter 的状态,来修改Text的值。这里暂且不讲状态,所以就来到我们这边的第一个知识点,WidgetTree。那么Widget树中的节点,Widget 又做了什么呢,
TODO:三棵树
上一篇:如何把图片存服务器?
下一篇:楼房的机房在哪里?