1、简介
Flutter 是 Google 推出并开源的移动应用开发框架,主打跨平台、高保真、高性能。开发者可以通过 Dart 语言开发 App,一套代码同时运行在 iOS 和 Android 平台。 Flutter 提供了丰富的组件、接口,开发者可以很快地为 Flutter 添加 Native(即原生开发,指基于平台原生语言来开发应用,flutter 可以和平台原生语言混合开发) 扩展。
1、跨平台自绘引擎
Flutter 与用于构建移动应用程序的其他大多数框架不同,因为 Flutter 既不使用 WebView,也不使用操作系统的原生控件。 相反 Flutter 使用自己的高性能渲染引擎来绘制 Widget(组件)。这样不仅可以保证在 Android 和 iOS 上 UI 的一致性,也可以避免对原生控件依赖而带来的限制及高昂的维护成本。
Flutter 底层使用 Skia 作为其 2D 渲染引擎,Skia 是 Google 的一个 2D 图形处理函数库,包含字型、坐标转换,以及点阵图,它们都有高效能且简洁的表现。Skia 是跨平台的,并提供了非常友好的 API,目前 Google Chrome 浏览器和 Android 均采用 Skia 作为其 2D 绘图引擎。
目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux、Fuchsia(Google 新的自研操作系统)等众多平台。
2、高性能
Flutter 高性能主要靠两点来保证:
1、Flutter App 采用 Dart 语言开发。Dart 在 JIT(即时编译)模式下,执行速度与 JavaScript 基本持平。但是 Dart 支持 AOT,当以 AOT 模式运行时,JavaScript 便远远追不上了。执行速度的提升对高帧率下的视图数据计算很有帮助。
2、Flutter 使用自己的渲染引擎来绘制 UI ,布局数据等由 Dart 语言直接控制,所以在布局过程中不需要像 RN 那样要在 JavaScript 和 Native 之间通信,这在一些滑动和拖动的场景下具有明显优势,因为在滑动和拖动过程往往都会引起布局发生变化,所以 JavaScript 需要和 Native 之间不停地同步布局信息,这和在浏览器中JavaScript 频繁操作 DOM 所带来的问题是类似的,都会导致比较可观的性能开销。
3、采用 Dart 语言开发
两个重要的概念:JIT 和 AOT。
程序主要有两种运行方式:静态编译
与动态解释
。
静态编译:程序在执行前程序会被提前编译为机器码(或中间字节码),通常将这种类型称为 AOT (Ahead of time)即 提前编译
。AOT 程序的典型代表是用 C/C++ 开发的应用,它们必须在执行前编译成机器码。通常我们区分是否为 AOT 的标准是看代码在执行之前是否需要编译
,只要需要编译,无论其编译产物是字节码还是机器码,都属于AOT。
动态解释:是在运行时将源码实时翻译为机器码来执行,通常将这种类型称为 JIT(Just-in-time)即即时编译
。JIT 的代表则非常多,如 JavaScript、python 等,事实上,所有脚本语言都支持 JIT 模式。
需要注意的是 JIT 和 AOT 指的是程序运行方式,和编程语言并非强关联的,有些语言既可以以 JIT 方式运行也可以以 AOT 方式运行,如 Python,它可以在第一次执行时编译成中间字节码,然后在之后执行时再将字节码实时转为机器码执行。
下面是 Dart 语言的特性:
开发效率高
Dart 运行时和编译器支持 Flutter 的两个关键特性的组合:
基于 JIT 的快速开发周期:Flutter 在开发阶段采用 JIT 模式,这样就避免了每次改动都要进行编译,极大地节省了开发时间。
基于 AOT 的发布包:Flutter 在发布时可以通过 AOT 生成高效的机器码以保证应用性能。
高性能
Flutter 旨在提供流畅、高保真的 UI 体验。为了实现这一点,Flutter 中需要能够在每个动画帧中运行大量的代码。这意味着需要一种既能保证高性能,也不会出现丢帧的编程语言,而 Dart 支持 AOT,在这一点上可以做得比 JavaScript 更好。
快速内存分配
Flutter 框架使用函数式流,这使得它在很大程度上依赖于底层的内存分配器。因此,拥有一个能够有效地处理琐碎任务的内存分配器将显得十分重要,在缺乏此功能的语言中,Flutter 将无法有效地工作。当然 Chrome V8 的 JavaScript 引擎在内存分配上也已经做的很好,事实上 Dart 开发团队的很多成员都是来自 Chrome 团队的,所以在内存分配上 Dart 并不能作为超越 JavaScript 的优势,而对于 Flutter 来说,它需要这样的特性,而 Dart 也正好满足而已。
类型安全和空安全
由于 Dart 是类型安全的语言,且 2.12 版本后也支持了空安全特性,所以 Dart 支持静态类型检测,可以在编译前发现一些类型的错误,并排除潜在问题,这一点对于前端开发者来说可能会更具有吸引力。与之不同的,JavaScript 是一个弱类型语言。相比之下,Dart 本身就支持静态类型,这是它的一个重要优势。
2、Flutter 框架结构
Flutter 从上到下可以分为三层:框架层、引擎层和嵌入层。
1、框架层
Flutter Framework,即框架层。这是一个纯 Dart 实现的 SDK,它实现了一套基础库,介绍如下:
1、Foundation 和 Animation、Painting、Gestures:在 Google 的一些视频中被合并为一个 dart UI 层,对应的是 Flutter 中的dart:ui
包,它是 Flutter Engine 暴露的底层 UI 库,提供动画、手势及绘制能力。
2、Rendering 层,即渲染层,这一层是一个抽象的布局层,它依赖于 Dart UI 层,渲染层会构建一棵由可渲染对象组成的渲染树
,当动态更新这些对象时,渲染树会找出变化的部分,然后更新渲染。渲染层可以说是 Flutter 框架层中最核心的部分,它除了确定每个渲染对象的位置、大小之外还要进行坐标变换、绘制(调用底层 dart:ui )。
3、Widgets 层是 Flutter 提供的一套基础组件库,在基础组件库之上,Flutter 还提供了 Material 和 Cupertino 两种视觉风格的组件库,它们分别实现了 Material 和 iOS 设计规范。
2、引擎层
Engine,即引擎层。毫无疑问是 Flutter 的核心, 该层主要是 C++ 实现,其中包括了 Skia 引擎、Dart 运行时(Dart runtime)、文字排版引擎等。在代码调用 dart:ui 库时,调用最终会走到引擎层,然后实现真正的绘制和显示。
3. 嵌入层
Embedder,即嵌入层。Flutter 最终渲染、交互是要依赖其所在平台的操作系统 API,嵌入层主要是将 Flutter 引擎 安装
到特定平台上。嵌入层采用了当前平台的语言编写,例如 Android 使用的是 Java 和 C++, iOS 和 macOS 使用的是 Objective-C 和 Objective-C++,Windows 和 Linux 使用的是 C++。 Flutter 代码可以通过嵌入层,以模块方式集成到现有的应用中,也可以作为应用的主体。Flutter 本身包含了各个常见平台的嵌入层,假如以后 Flutter 要支持新的平台,则需要针对该新的平台编写一个嵌入层。