Flutter之原理解析

Flutter之原理解析

Flutter 是 Google推出并開(kāi)源的移動(dòng)應(yīng)用開(kāi)發(fā)框架,主打 跨平臺(tái)、高保真、高性能。開(kāi)發(fā)者可以通過(guò) Dart語(yǔ)言開(kāi)發(fā) App,一套代碼同時(shí)運(yùn)行在 iOS 和 Android平臺(tái)。 Flutter提供了豐富的組件、接口,開(kāi)發(fā)者可以很快地為 Flutter添加 native擴(kuò)展。同時(shí) Flutter還使用Native引擎渲染視圖,這無(wú)疑能為用戶提供良好的體驗(yàn)。

在解析原理之前,首先讓我們思考以下幾個(gè)關(guān)于Flutter的問(wèn)題:

  1. 怎么實(shí)現(xiàn)跨平臺(tái)的?原理是什么?
  2. 為什么說(shuō) fullter 的 render 性能接近于原生?
  3. 對(duì)比使用 web 的開(kāi)發(fā)方式(RN、WEEX)有什么好處?

怎么實(shí)現(xiàn)跨平臺(tái)的?原理是什么?

在回答這個(gè)問(wèn)題之前, 我們需要先了解幾個(gè)操作系統(tǒng)的基本原理。

UI系統(tǒng)

UI系統(tǒng)是指通過(guò)某個(gè)平臺(tái)實(shí)現(xiàn)的一套 GUI(圖形用戶界面) 系統(tǒng)。
簡(jiǎn)單來(lái)說(shuō)用戶可以通過(guò) GUI 系統(tǒng)使用鼠標(biāo)、鍵盤(pán)等硬件設(shè)備與操作系統(tǒng)打交道。
這里所說(shuō)的平時(shí)指的是操作系統(tǒng),如 Android、ios 或者 wins、macOS。
各個(gè)平臺(tái)UI系統(tǒng)的原理是相通的,也就是說(shuō)無(wú)論是Android還是iOS,他們將一個(gè)用戶界面展示到屏幕的流程是相似的。

下面我們來(lái)了解下UI系統(tǒng)的基本原理:

硬件繪圖基本原理

我們知道顯示器(屏幕)是由一個(gè)個(gè)物理顯示單元組成,每一個(gè)單元我們可以稱(chēng)之為一個(gè)物理像素點(diǎn),而每一個(gè)像素點(diǎn)可以發(fā)出多種顏色,顯示器成相的原理就是在不同的物理像素點(diǎn)上顯示不同的顏色,最終構(gòu)成完整的圖像。

一個(gè)像素點(diǎn)能發(fā)出的所有顏色總數(shù)是顯示器的一個(gè)重要指標(biāo),比如我們所說(shuō)的1600萬(wàn)色的屏幕就是指一個(gè)像素點(diǎn)可以顯示出1600萬(wàn)種顏色。

為了更新顯示畫(huà)面,顯示器是以固定的頻率刷新(從GPU取數(shù)據(jù)),比如有一部手機(jī)屏幕的刷新頻率是 60Hz。當(dāng)一幀圖像繪制完畢后準(zhǔn)備繪制下一幀時(shí),顯示器會(huì)發(fā)出一個(gè)垂直同步信號(hào)(如VSync), 60Hz的屏幕就會(huì)一秒內(nèi)發(fā)出 60次這樣的信號(hào)。而這個(gè)信號(hào)主要是用于同步CPU、GPU和顯示器的。一般地來(lái)說(shuō),計(jì)算機(jī)系統(tǒng)中,CPU、GPU和顯示器以一種特定的方式協(xié)作:CPU將計(jì)算好的顯示內(nèi)容提交給 GPU,GPU渲染后放入幀緩沖區(qū),然后視頻控制器按照同步信號(hào)從幀緩沖區(qū)取幀數(shù)據(jù)傳遞給顯示器顯示。

image

操作系統(tǒng)繪制API的封裝

由于最終的圖形計(jì)算和繪制都是由相應(yīng)的硬件來(lái)完成,而直接操作硬件的指令通常都會(huì)有操作系統(tǒng)屏蔽,應(yīng)用開(kāi)發(fā)者通常不會(huì)直接面對(duì)硬件,操作系統(tǒng)屏蔽了這些底層硬件操作后會(huì)提供一些封裝后的API供操作系統(tǒng)之上的應(yīng)用調(diào)用。

但是對(duì)于應(yīng)用開(kāi)發(fā)者來(lái)說(shuō),直接調(diào)用這些操作系統(tǒng)提供的API是比較復(fù)雜和低效的,因?yàn)椴僮飨到y(tǒng)提供的API往往比較基礎(chǔ),直接調(diào)用需要了解API的很多細(xì)節(jié)。

正是因?yàn)檫@個(gè)原因,幾乎所有用于開(kāi)發(fā)GUI程序的編程語(yǔ)言都會(huì)在操作系統(tǒng)之上再封裝一層,將操作系統(tǒng)原生API封裝在一個(gè)編程框架和模型中,然后定義一種簡(jiǎn)單的開(kāi)發(fā)規(guī)則來(lái)開(kāi)發(fā)GUI應(yīng)用程序。

例如:
Android SDK 正是封裝了Android操作系統(tǒng)API,提供了一個(gè)“UI描述文件XML+Java操作DOM”的UI系統(tǒng)。
iOS的UIKit 對(duì)View的抽象也是一樣的,他們都將操作系統(tǒng)API抽象成一個(gè)基礎(chǔ)對(duì)象(如用于2D圖形繪制的Canvas),然后再定義一套規(guī)則來(lái)描述UI,如UI樹(shù)結(jié)構(gòu),UI操作的單線程原則等。

說(shuō)到這我想大家應(yīng)該明白Flutter是怎么實(shí)現(xiàn)跨平臺(tái)的了。

我們可以看到,無(wú)論是Android SDK還是iOS的UIKit 的職責(zé)都是相同的,它們只是語(yǔ)言載體和底層的系統(tǒng)不同而已。那么可不可以實(shí)現(xiàn)這么一個(gè)UI系統(tǒng):可以使用同一種編程語(yǔ)言開(kāi)發(fā),然后針對(duì)不同操作系統(tǒng)API抽象一個(gè)對(duì)上接口一致,對(duì)下適配不同操作系統(tǒng)的的中間層,然后在打包編譯時(shí)再使用相應(yīng)的中間層代碼?如果可以做到,那么我們就可以使用同一套代碼編寫(xiě)跨平臺(tái)的應(yīng)用了。

而Flutter的原理正是如此,它提供了一套Dart API,然后在底層通過(guò)skia這種跨平臺(tái)的繪制庫(kù)(內(nèi)部會(huì)調(diào)用操作系統(tǒng)API)實(shí)現(xiàn)了一套代碼跨多端。

image

這就是Flutter實(shí)現(xiàn)跨平臺(tái)的原理。

由于Dart API也是調(diào)用操作系統(tǒng)API,所以說(shuō)它的性能接近原生。

注意,雖然Dart是先調(diào)用了skia,skia才會(huì)調(diào)用操作系統(tǒng)API,但是這仍然是原生渲染,因?yàn)閟kia只是操作系統(tǒng)API的一個(gè)封裝庫(kù),所以性能不能有什么損失。

說(shuō)到這大家應(yīng)該已經(jīng)能明白開(kāi)頭提的前兩個(gè)問(wèn)題吧!~~~

Flutter 實(shí)現(xiàn)原理

Fluuter官網(wǎng) 上,google 給出了一個(gè)非常詳盡的圖來(lái)解釋 Flutter的原理:

image

讓我們來(lái)分析下這張圖:

  1. GPU的 VSync 信號(hào)同步到 UI線程。
  2. UI線程使用 Dart來(lái)構(gòu)建抽象的視圖結(jié)構(gòu)。
  3. 這份視圖數(shù)據(jù)結(jié)構(gòu)在 GPU 線程進(jìn)行圖層合成。
  4. 視圖數(shù)據(jù)提供給 Skia 引擎渲染為 GPU 數(shù)據(jù)。
  5. 這些數(shù)據(jù)通過(guò) OpenGL或者 Vulkan 提供給 GPU

所以 Flutter 并不關(guān)心顯示器、視頻控制器以及 GPU 具體工作,它只關(guān)心向 GPU 提供視圖數(shù)據(jù),在顯示器會(huì)發(fā)出一個(gè)垂直同步信號(hào)(VSync),盡可能快地在兩個(gè) VSync 信號(hào)之間計(jì)算并合成視圖數(shù)據(jù),并且把數(shù)據(jù)提供給 GPU 。

說(shuō)到這大家應(yīng)該對(duì) Flutter 的原理有個(gè)基本的認(rèn)識(shí)了吧。下面讓我們來(lái)看下Flutter是如何被設(shè)計(jì)的。

Flutter是如何設(shè)計(jì)的

首先讓我們來(lái)看一下 google 官方給出的架構(gòu)圖:
image
  • FLutter Engine
    這是一個(gè)純 C++實(shí)現(xiàn)的 SDK,其中囊括了 Skia引擎、Dart運(yùn)行時(shí)、文字排版引擎等。
    簡(jiǎn)單來(lái)說(shuō)它就是一個(gè) dart 運(yùn)行時(shí),可以以 JIT(動(dòng)態(tài)編譯) 或者 AOT(靜態(tài)編譯) 的方式運(yùn)行 dart 代碼。

  • Flutter Framework
    最上層應(yīng)用,我們的應(yīng)用都是圍繞這層來(lái)構(gòu)建,所以該層也是我們打交道最多的層。
    改層是一個(gè)純 Dart實(shí)現(xiàn)的 SDK,類(lèi)似于 React在 JavaScript中的作用。它實(shí)現(xiàn)了一套基礎(chǔ)庫(kù), 用于處理動(dòng)畫(huà)、繪圖和手勢(shì)。并且基于繪圖封裝了一套 UI組件庫(kù),然后根據(jù) Material 和Cupertino兩種視覺(jué)風(fēng)格區(qū)分開(kāi)來(lái)。

    • 【Foundation】 在最底層,主要定義底層工具類(lèi)和方法,以提供給其他層使用。
    • 【Animation】是動(dòng)畫(huà)相關(guān)的類(lèi),一些動(dòng)畫(huà)相關(guān)的都在該類(lèi)中定義。
    • 【Painting】封裝了 Flutter Engine 提供的繪制接口,例如繪制縮放圖像、插值生成陰影、繪制盒模型邊框等。
    • 【Gesture】提供處理手勢(shì)識(shí)別和交互的功能。
    • 【Rendering】是框架中的渲染庫(kù)??丶匿秩局饕ㄈ齻€(gè)階段:布局(Layout)、繪制(Paint)、合成(Composite)。
    • 【W(wǎng)idget】控件層。所有控件的基類(lèi)都是 Widget,Widget 的數(shù)據(jù)都是只讀的, 不能改變。
    • 【Material】&【Cupertino】這是在 Widget 層之上框架為開(kāi)發(fā)者提供的基于兩套設(shè)計(jì)語(yǔ)言實(shí)現(xiàn)的 UI 控件,可以幫助我們的 App 在不同平臺(tái)上提供接近原生的用戶體驗(yàn)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容