面试官: 你有用过Flutter吗? Flutter架构是怎么样,为什么会比其他如ReactNative好
心理分析: 面试官所在的项目是用Flutter 开发的,或者正在转Flutter这种技术。如果你不会,面试官在第一眼会认为后面来应聘的人或许会、为了杜绝这种情况发生,你一定要说以前研究过,写过相关代码。其实”有用过Flutter“对大多数求职只是 会与不会 的问题。这不是面试官 想了解的。面试官的重点 你了解的有多深。
接下来,会问你他的原理 你是怎么看。 它的优缺点。为什么比其他的好。从原理层来解析。这才是最难的。
这篇文章 从原理层说明他们的区别
求职者: 应该做好被虐的准备。如果看了这篇文章,应付下来基本没有多大的问题
在Flutter诞生之前,已经有许多跨平台UI框架的方案,比如基于WebView的Cordova、AppCan等,还有使用HTML+JavaScript渲染成原生控件的React Native、Weex等。
1.0 框架架构
反观Flutter
首先看一下Flutter的架构图
1.1 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内部,这就使得它具有了很好的跨端一致性。
从架构图可以看出,从头到尾重写一套跨平台的UI框架,包括UI控件、渲染逻辑甚至开发语言。渲染引擎依靠跨平台的Skia图形库来实现,依赖系统的只有图形绘制相关的接口,可以在最大程度上保证不同平台、不同设备的体验一致性,逻辑处理使用支持AOT的Dart语言,执行效率也比JavaScript高得多
目前上主流的思想,都希望将各个ui控件接耦,慢慢演变出组件化的思想。
Flutter控件主要分为两大类,
StatelessWidget
用来展示静态的文本或者图片,如果控件需要根据外部数据或者用户操作来改变的话,就需要使用StatefulWidget
。
State的概念也是来源于Facebook的流行Web框架React,React风格的框架中使用控件树和各自的状态来构建界面,当某个控件的状态发生变化时由框架负责对比前后状态差异并且采取最小代价来更新渲染结果。
1.3 绘图基本原理
从下图这里可以看出 Flutter和 React-Native之众的本质区别:React-Native之类只是扩展调用 OEM组件,而 Flutter是自己渲染。
在 Flutter Architecture的解释中,Google还提供了一张更为详尽的图来解释 Flutter的原理:
这张图解释得更清晰一些:Flutter只关心向 GPU提供视图数据,GPU的 VSync信号同步到 UI线程,UI线程使用 Dart来构建抽象的视图结构,这份数据结构在 GPU线程进行图层合成,视图数据提供给 Skia引擎渲染为 GPU数据,这些数据通过 OpenGL或者 Vulkan提供给 GPU。
所以 Flutter并不关心显示器、视频控制器以及 GPU具体工作,它只关心 GPU发出的 VSync信号,尽可能快地在两个 VSync信号之间计算并合成视图数据,并且把数据提供给 GPU。
了解 Flutter的基本概念后,自然有几个疑问亟待解决。
1.4.1 为什么使用 Dart?能说说其中的原因吗
1.4.2 Skia是什么? 为什么Flutter会引入Skia
前面提到了 Flutter只关心如何构建视图抽象结构,向 GPU提供视图数据。Skia就是 Flutter向 GPU提供数据的途径。
1.4.3 Flutter的架构是怎么样的,你是怎么理解FLutter的架构
我们可能只知道 Flutter做了什么,始终都还没有从侧面观察 Flutter的整个架构设计,了解 Flutter如何去做。
这张图了解过 Flutter的人可能很多地方都看过,这边来详细解释一下:
Flutter Framework: 这是一个纯 Dart实现的 SDK,类似于 React在 JavaScript中的作用。它实现了一套基础库, 用于处理动画、绘图和手势。并且基于绘图封装了一套 UI组件库,然后根据 Material 和Cupertino两种视觉风格区分开来。这个纯 Dart实现的 SDK被封装为了一个叫作 dart:ui的 Dart库。我们在使用 Flutter写 App的时候,直接导入这个库即可使用组件等功能。
Flutter Engine: 这是一个纯 C++实现的 SDK,其中囊括了 Skia引擎、Dart运行时、文字排版引擎等。不过说白了,它就是 Dart的一个运行时,它可以以 JIT、JIT Snapshot 或者 AOT的模式运行 Dart代码。在代码调用 dart:ui库时,提供 dart:ui库中 Native Binding 实现。 不过别忘了,这个运行时还控制着 VSync信号的传递、GPU数据的填充等,并且还负责把客户端的事件传递到运行时中的代码。
在了解屏幕绘图的基本原理和 Flutter的一个整体概念后,我们下面详细地来看一下 Flutter的大概实现。
要理解 Flutter的原理,我们从 entry point开始看 Flutter的代码。由于应用框架大同小异,所以下文提及 Flutter的代码即指代 Flutter Engine的代码,而非 Flutter Dart Framework代码。
下图是我简单整理了一下 Flutter应用启动后的执行顺序
在应用的 View Controller 初始化后,会实例化一个 Flutter project的抽象(以下简称 project)。project会初始化一个 platform view的抽象实例,这个抽象实例会负责创建 Flutter 的运行时(以下简称 engine)。
当 View Controller将要显示时,调用 project查找和组合 Flutter的应用资源 bundle,并且把资源提供给 engine。
engine在真正需要执行资源 bundle时才会创建 Dart执行的环境(懒加载,以下简称 Dart Controller),然后设置视图窗口的一些属性等东西(这是绘图引擎必需的)。
然后 engine中的 Dart Controller会加载 Dart代码并执行,执行的过程中会调用 dart:ui的 native binding实现向 GPU提供数据。
1.4.4 Flutter SDK体积为什么非常大?这个你知道吗
1.4.5 Flutter可以跑多个实例吗?(连环炮)
可以的。