Flutter之原理解析

Flutter之原理解析

Flutter 是 Google推出并开源的移动应用开发框架,主打 跨平台、高保真、高性能。开发者可以通过 Dart语言开发 App,一套代码同时运行在 iOS 和 Android平台。 Flutter提供了丰富的组件、接口,开发者可以很快地为 Flutter添加 native扩展。同时 Flutter还使用Native引擎渲染视图,这无疑能为用户提供良好的体验。

在解析原理之前,首先让我们思考以下几个关于Flutter的问题:

  1. 怎么实现跨平台的?原理是什么?
  2. 为什么说 fullter 的 render 性能接近于原生?
  3. 对比使用 web 的开发方式(RN、WEEX)有什么好处?

怎么实现跨平台的?原理是什么?

在回答这个问题之前, 我们需要先了解几个操作系统的基本原理。

UI系统

UI系统是指通过某个平台实现的一套 GUI(图形用户界面) 系统。
简单来说用户可以通过 GUI 系统使用鼠标、键盘等硬件设备与操作系统打交道。
这里所说的平时指的是操作系统,如 Android、ios 或者 wins、macOS。
各个平台UI系统的原理是相通的,也就是说无论是Android还是iOS,他们将一个用户界面展示到屏幕的流程是相似的。

下面我们来了解下UI系统的基本原理:

硬件绘图基本原理

我们知道显示器(屏幕)是由一个个物理显示单元组成,每一个单元我们可以称之为一个物理像素点,而每一个像素点可以发出多种颜色,显示器成相的原理就是在不同的物理像素点上显示不同的颜色,最终构成完整的图像。

一个像素点能发出的所有颜色总数是显示器的一个重要指标,比如我们所说的1600万色的屏幕就是指一个像素点可以显示出1600万种颜色。

为了更新显示画面,显示器是以固定的频率刷新(从GPU取数据),比如有一部手机屏幕的刷新频率是 60Hz。当一帧图像绘制完毕后准备绘制下一帧时,显示器会发出一个垂直同步信号(如VSync), 60Hz的屏幕就会一秒内发出 60次这样的信号。而这个信号主要是用于同步CPU、GPU和显示器的。一般地来说,计算机系统中,CPU、GPU和显示器以一种特定的方式协作:CPU将计算好的显示内容提交给 GPU,GPU渲染后放入帧缓冲区,然后视频控制器按照同步信号从帧缓冲区取帧数据传递给显示器显示。

image

操作系统绘制API的封装

由于最终的图形计算和绘制都是由相应的硬件来完成,而直接操作硬件的指令通常都会有操作系统屏蔽,应用开发者通常不会直接面对硬件,操作系统屏蔽了这些底层硬件操作后会提供一些封装后的API供操作系统之上的应用调用。

但是对于应用开发者来说,直接调用这些操作系统提供的API是比较复杂和低效的,因为操作系统提供的API往往比较基础,直接调用需要了解API的很多细节。

正是因为这个原因,几乎所有用于开发GUI程序的编程语言都会在操作系统之上再封装一层,将操作系统原生API封装在一个编程框架和模型中,然后定义一种简单的开发规则来开发GUI应用程序。

例如:
Android SDK 正是封装了Android操作系统API,提供了一个“UI描述文件XML+Java操作DOM”的UI系统。
iOS的UIKit 对View的抽象也是一样的,他们都将操作系统API抽象成一个基础对象(如用于2D图形绘制的Canvas),然后再定义一套规则来描述UI,如UI树结构,UI操作的单线程原则等。

说到这我想大家应该明白Flutter是怎么实现跨平台的了。

我们可以看到,无论是Android SDK还是iOS的UIKit 的职责都是相同的,它们只是语言载体和底层的系统不同而已。那么可不可以实现这么一个UI系统:可以使用同一种编程语言开发,然后针对不同操作系统API抽象一个对上接口一致,对下适配不同操作系统的的中间层,然后在打包编译时再使用相应的中间层代码?如果可以做到,那么我们就可以使用同一套代码编写跨平台的应用了。

而Flutter的原理正是如此,它提供了一套Dart API,然后在底层通过skia这种跨平台的绘制库(内部会调用操作系统API)实现了一套代码跨多端。

image

这就是Flutter实现跨平台的原理。

由于Dart API也是调用操作系统API,所以说它的性能接近原生。

注意,虽然Dart是先调用了skia,skia才会调用操作系统API,但是这仍然是原生渲染,因为skia只是操作系统API的一个封装库,所以性能不能有什么损失。

说到这大家应该已经能明白开头提的前两个问题吧!~~~

Flutter 实现原理

在 Fluuter官网 上,google 给出了一个非常详尽的图来解释 Flutter的原理:

image

让我们来分析下这张图:

  1. GPU的 VSync 信号同步到 UI线程。
  2. UI线程使用 Dart来构建抽象的视图结构。
  3. 这份视图数据结构在 GPU 线程进行图层合成。
  4. 视图数据提供给 Skia 引擎渲染为 GPU 数据。
  5. 这些数据通过 OpenGL或者 Vulkan 提供给 GPU

所以 Flutter 并不关心显示器、视频控制器以及 GPU 具体工作,它只关心向 GPU 提供视图数据,在显示器会发出一个垂直同步信号(VSync),尽可能快地在两个 VSync 信号之间计算并合成视图数据,并且把数据提供给 GPU 。

说到这大家应该对 Flutter 的原理有个基本的认识了吧。下面让我们来看下Flutter是如何被设计的。

Flutter是如何设计的

首先让我们来看一下 google 官方给出的架构图:
image
  • FLutter Engine
    这是一个纯 C++实现的 SDK,其中囊括了 Skia引擎、Dart运行时、文字排版引擎等。
    简单来说它就是一个 dart 运行时,可以以 JIT(动态编译) 或者 AOT(静态编译) 的方式运行 dart 代码。

  • Flutter Framework
    最上层应用,我们的应用都是围绕这层来构建,所以该层也是我们打交道最多的层。
    改层是一个纯 Dart实现的 SDK,类似于 React在 JavaScript中的作用。它实现了一套基础库, 用于处理动画、绘图和手势。并且基于绘图封装了一套 UI组件库,然后根据 Material 和Cupertino两种视觉风格区分开来。

    • 【Foundation】 在最底层,主要定义底层工具类和方法,以提供给其他层使用。
    • 【Animation】是动画相关的类,一些动画相关的都在该类中定义。
    • 【Painting】封装了 Flutter Engine 提供的绘制接口,例如绘制缩放图像、插值生成阴影、绘制盒模型边框等。
    • 【Gesture】提供处理手势识别和交互的功能。
    • 【Rendering】是框架中的渲染库。控件的渲染主要包括三个阶段:布局(Layout)、绘制(Paint)、合成(Composite)。
    • 【Widget】控件层。所有控件的基类都是 Widget,Widget 的数据都是只读的, 不能改变。
    • 【Material】&【Cupertino】这是在 Widget 层之上框架为开发者提供的基于两套设计语言实现的 UI 控件,可以帮助我们的 App 在不同平台上提供接近原生的用户体验。

你可能感兴趣的:(Flutter之原理解析)