Flutter入门系列-Flutter介绍

一、简单介绍下Flutter框架,以及它的优缺点?

Flutter 是 Google 推出的一套开源跨平台UI框架,可以快速地在Android、iOS和Web平台上构建高质量的原生用户界面。同时,Flutter 还是 Google 新研发的 Fuchsia 操作系统的默认开发套件。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。Flutter采用现代响应式框架构建,其中心思想是使用组件来构建应用的UI。当组件的状态发生改变时,组件会重构它的描述,Flutter会对比之前的描述,以确定底层渲染树从当前状态转换到下一个状态所需要的最小更改。

优点

1. 热重载(Hot Reload),利用 Android Studio 直接一个ctrl+s就可以保存并重载,模拟器立马就可以看见效果,相比原生冗长的编译过程强很多;

2. 一切皆为Widget的理念,对于Flutter来说,手机应用里的所有东西都是 Widget,通过可组合的空间集合、丰富的动画库以及分层课扩展的架构实现了富有感染力的灵活界面设计;

3. 借助可移植的GPU加速的渲染引擎以及高性能本地代码运行时以达到跨平台设备的高质量用户体验。简单来说就是:最终结果就是利用Flutter构建的应用在运行效率上会和原生应用差不多。

缺点

1.不支持热更新;

2.三方库有限,需要自己造轮子;【现在有很多了】

3. Dart语言编写,增加了学习难度,并且学习了Dart之后无其他用处,相比JS和Java来说。

二、介绍下Flutter的理念架构

其实也就是下面这张图。

image.png

由上图可知,Flutter 框架自下而上分为 Embedder、Engine 和 Framework 三层。其中,Embedder 是操作系统适配层,实现了渲染 Surface 设置,线程设置,以及平台插件等平台相关特性的适配;Engine 层负责图形绘制、文字排版和提供 Dart 运行时,Engine层具有独立虚拟机,正是由于它的存在,Flutter程序才能运行在不同的平台上,实现跨平台运行;Framework层则是使用Dart编写的一套基础视图库,包含了动画、图形绘制和手势识别等功能,是使用频率最高的一层。

三、Flutter的FrameWork层和Engine层,以及它们的作用

Flutter 的 FrameWork 层是用 Drat 编写的框架(SDK),它实现了一套基础库,包含Material(Android风格UI)和 Cupertino(iOS风格)的UI界面,下面是通用的 Widgets(组件),之后是一些动画、绘制、渲染、手势库等。这个纯 Dart 实现的SDK被封装为了一个叫作 dart:ui的 Dart库。我们在使用 Flutter写 App的时候,直接导入这个库即可使用组件等功能。

Flutter的 Engine 层是 Skia 2D的绘图引擎库,其前身是一个向量绘图软件,Chrome和 Android均采用 Skia作为绘图引擎。Skia提供了非常友好的 API,并且在图形转换、文字渲染、位图渲染方面都提供了友好、高效的表现。Skia是跨平台的,所以可以被嵌入到 Flutter的 iOS SDK中,而不用去研究 iOS闭源的 Core Graphics / Core Animation。Android自带了 Skia,所以 Flutter Android SDK要比 iOS SDK小很多。

四、介绍下Widget、State、Context 概念

1. Widget:

在Flutter中,几乎所有东西都是Widget。将一个Widget想象为一个可视化的组件(或与应用可视化方面交互的组件),当你需要构建与布局直接或间接相关的任何内容时,你正在使用Widget。

2. Widget树:

Widget以树结构进行组织。包含其他Widget的widget被称为父Widget(或widget容器)。包含在父widget中的widget被称为子Widget。

3. Context:

仅仅是已创建的所有Widget树结构中的某个Widget的位置引用。简而言之,将context作为widget树的一部分,其中context所对应的widget被添加到此树中。一个context只从属于一个widget,它和widget一样是链接在一起的,并且会形成一个context树。

4. State:

定义了StatefulWidget 实例的行为,它包含了用于“交互/干预” Widget信息的行为和布局。应用于State的任何更改都会强制重建Widget。

五、StatelessWidget和StatefulWidget两种状态组件类

1. StatelessWidget:

一旦创建就不关心任何变化,在下次构建之前都不会改变。它们除了依赖于自身的配置信息(在父节点构建时提供)外不再依赖于任何其他信息。比如典型的Text、Row、Column、Container等,都是StatelessWidget。它的生命周期相当简单:初始化、通过build()渲染。

2. StatefulWidget:

在生命周期内,该类Widget所持有的数据可能会发生变化,这样的数据被称为State,这些拥有动态内部数据的Widget被称为StatefulWidget。比如复选框、Button等。State会与Context相关联,并且此关联是永久性的,State 对象将永远不会改变其 Context,即使可以在树结构周围移动,也仍将与该context相关联。当state与context关联时,state被视为已挂载。StatefulWidget由两部分组成,在初始化时必须要在createState()时初始化一个与之相关的State对象。

六、StatefulWidget 的生命周期

Flutter 的 Widget 分为 StatelessWidget 和 StatefulWidget 两种。其中,StatelessWidget 是无状态的,StatefulWidget 是有状态的,因此实际使用时,更多的是 StatefulWidget。StatefulWidget 的生命周期如下:


image.png

1. initState()

Widget 初始化当前 State,在当前方法中是不能获取到 Context 的,如想获取,可以试试 Future.delayed()

2. didChangeDependencies()

在 initState() 后调用,State对象依赖关系发生变化的时候也会调用。

Flutter原理篇-didChangeDependencies什么时候被调用 - 知乎

3. deactivate():

当 State 被暂时从视图树中移除时会调用这个方法,页面切换时也会调用该方法,和Android里的 onPause 差不多。

4. dispose()

Widget 销毁时调用。

5. didUpdateWidget

Widget 状态发生变化的时候调用。

Flutter state生命周期方法之didChangeDependencies 、didUpdateWidget

七、Widgets、RenderObjects 和 Elements的关系

首先看一下这几个对象的含义及作用。

1. Widget :仅用于存储渲染所需要的信息。

2. RenderObject :负责管理布局、绘制等操作。

3. Element :才是这颗巨大的控件树上的实体。

Widget 会被 inflate(填充)到 Element,并由 Element 管理底层渲染树。Widget 并不会直接管理状态及渲染,而是通过 State 这个对象来管理状态。Flutter 创建Element的可见树,相对于Widget来说,是可变的,通常界面开发中,我们不用直接操作 Element,而是由框架层实现内部逻辑。就如一个UI视图树中,可能包含有多个 TextWidget (Widget被使用多次),但是放在内部视图树的视角,这些TextWidget都是填充到一个个独立的Element中。Element 会持有 renderObject 和 widget的实例。记住,Widget 只是一个配置,RenderObject 负责管理布局、绘制等操作。

在第一次创建 Widget 的时候,会对应创建一个 Element, 然后将该元素插入树中。如果之后 Widget 发生了变化,则将其与旧的 Widget 进行比较,并且相应地更新 Element。重要的是,Element 不会被重建,只是更新而已。

八、什么是状态管理,你了解哪些状态管理框架?

Flutter 中的状态和前端 React 中的状态概念是一致的。React 框架的核心思想是组件化,应用由组件搭建而成,组件最重要的概念就是状态,状态是一个组件的UI数据模型,是组件渲染时的数据依据。

Flutter的状态可以分为全局状态和局部状态两种。常用的状态管理有 ScopedModel、BLoC、Redux / FishRedux 和 Provider。详细使用情况和差异可以自行了解。

九、Flutter的绘制流程

image.png

Flutter 只关心向 GPU 提供视图数据,GPU的 VSync 信号同步到 UI线程,UI 线程使用 Dart来构建抽象的视图结构,这份数据结构在 GPU 线程进行图层合成,视图数据提供给Skia引擎之后渲染为 GPU数据,这些数据通过 OpenGL或者 Vulkan提供给 GPU。

十、Flutter的线程管理模型

默认情况下,Flutter Engine 层会创建一个Isolate,并且 Dart 代码默认就运行在这个主Isolate上。必要时可以使用 spawnUri 和 spawn 两种方式来创建新的 Isolate,在 Flutter中,新创建的Isolate由Flutter进行统一的管理。

事实上,Flutter Engine 自己不创建和管理线程,Flutter Engine线程的创建和管理是Embeder负责的,Embeder指的是将引擎移植到平台的中间层代码,Flutter Engine 层的架构示意图如下图所示。

image.png

在 Flutter 的架构中,Embeder提供四个Task Runner,分别是Platform Task Runner、UI Task Runner Thread、GPU Task Runner 和 IO Task Runner,每个Task Runner负责不同的任务, Flutter Engine 不在乎Task Runner运行在哪个线程,但是它需要线程在整个生命周期里面保持稳定。

十一、Flutter 是如何与原生Android、iOS进行通信的?

Flutter 通过 PlatformChannel 与原生进行交互,其中 PlatformChannel 分为三种:

BasicMessageChannel :用于传递字符串和半结构化的信息。

MethodChannel :用于传递方法调用(method invocation)。

EventChannel : 用于数据流(event streams)的通信。

同时 Platform Channel 并非是线程安全的 ,更多详细可查阅闲鱼技术的 《深入理解Flutter Platform Channel》。

十二、简述Flutter 的热重载

Flutter 的热重载是基于 JIT 编译模式的代码增量同步。由于 JIT 属于动态编译,能够将 Dart 代码编译成生成中间代码,让 Dart VM 在运行时解释执行,因此可以通过动态更新中间代码实现增量同步。

热重载的流程可以分为 5 步,包括:扫描工程改动、增量编译、推送更新、代码合并、Widget 重建。Flutter 在接收到代码变更后,并不会让 App 重新启动执行,而只会触发 Widget 树的重新绘制,因此可以保持改动前的状态,大大缩短了从代码修改到看到修改产生的变化之间所需要的时间。

另一方面,由于涉及到状态的保存与恢复,涉及状态兼容与状态初始化的场景,热重载是无法支持的,如改动前后 Widget 状态无法兼容、全局变量与静态属性的更改、main 方法里的更改、initState 方法里的更改、枚举和泛型的更改等。

可以发现,热重载提高了调试 UI 的效率,非常适合写界面样式这样需要反复查看修改效果的场景。但由于其状态保存的机制所限,热重载本身也有一些无法支持的边界

十三、Flutter 是怎么运转的?

与用于构建移动应用程序的其他大多数框架不同,Flutter 是重写了一整套包括底层渲染逻辑和上层开发语言的完整解决方案。这样不仅可以保证视图渲染在 Android 和 iOS 上的高度一致性(即高保真),在代码执行效率和渲染性能上也可以媲美原生 App 的体验(即高性能)。这就是Flutter 和其他跨平台方案的本质区别。React Native 之类的框架,只是通过 JavaScript 虚拟机扩展调用系统组件,由 Android 和 iOS 系统进行组件的渲染;

Flutter 则是自己完成了组件渲染的闭环。那么,Flutter 是怎么完成组件渲染的呢?这需要从图像显示的基本原理说起。在计算机系统中,图像的显示需要 CPU、GPU 和显示器一起配合完成:CPU 负责图像数据计算,GPU 负责图像数据渲染,而显示器则负责最终图像显示。CPU 把计算好的、需要显示的内容交给 GPU,由 GPU 完成渲染后【确定每个像素点的像素值】放入帧缓冲区,随后视频控制器根据垂直同步信号(VSync)以每秒 60 次的速度,从帧缓冲区读取帧数据交由显示器完成图像显示。操作系统在呈现图像时遵循了这种机制,而 Flutter 作为跨平台开发框架也采用了这种底层方案。下面有一张更为详尽的示意图来解释 Flutter 的绘制原理。

 Flutter 绘制原理可以看到,Flutter 关注如何尽可能快地在两个硬件时钟的 VSync 信号之间计算并合成视图数据,然后通过 Skia 交给 GPU 渲染:UI 线程使用 Dart 来构建视图结构数据,这些数据会在 GPU 线程进行图层合成,随后交给 Skia 引擎加工成 GPU 数据,而这些数据会通过 OpenGL 最终提供给 GPU 渲染。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值