Flutter 是怎麼運轉的?
Flutter 是重寫了一整套包括底層渲染邏輯和上層開發語言的完整解決方案。
Flutter 和其他跨平臺方案的本質區別:
React Native 之類的框架,只是通過 JavaScript 虛擬機器擴充套件呼叫系統元件,由 Android 和 iOS 系統進行元件的渲染;
Flutter 則是自己完成了元件渲染的閉環。
Flutter 是怎麼完成元件渲染的呢?
在計算機系統中,CPU 負責影象資料計算,GPU 負責影象資料渲染,而顯示器則負責最終影象顯示。 CPU 把計算好的、需要顯示的內容交給 GPU,由 GPU 完成渲染後放入幀緩衝區,隨後視訊控制器根據垂直同步訊號(VSync)以每秒 60 次的速度,從幀緩衝區讀取幀資料交由顯示器完成影象顯示。
![Flutter核心技術與實戰 04 | Flutter區別於其他方案的關鍵技術是什麼?](https://i.iter01.com/images/6116e9d47730b48aadd9e5a415f757b8da54866d780fe7dacfcf6807342bed4b.png)
Skia 是什麼?
Skia 是一款用 C++ 開發的、效能彪悍的 2D 影象繪製引擎,架構於 Skia 之上的 Flutter,也因此擁有了徹底的跨平臺渲染能力。
Flutter 的原理
![Flutter核心技術與實戰 04 | Flutter區別於其他方案的關鍵技術是什麼?](https://i.iter01.com/images/79f99504f5265e6947cbaf9947f4d8fb381859bd2932b96c2fc5f906a460a00b.png)
- Embedder 是作業系統適配層,實現了渲染 Surface 設定,執行緒設定,以及平臺外掛等平臺相關特性的適配。
- Engine 層主要包含 Skia、Dart 和 Text,實現了 Flutter 的渲染引擎、文字排版、事件處理和 Dart 執行時等功能。Skia 和 Text 為上層介面提供了呼叫底層渲染和排版的能力,Dart 則為 Flutter 提供了執行時呼叫 Dart 和渲染引擎的能力。而 Engine 層的作用,則是將它們組合起來,從它們生成的資料中實現檢視渲染。
- Framework 層則是一個用 Dart 實現的 UI SDK,包含了動畫、圖形繪製和手勢識別等功能。為了在繪製控制元件等固定樣式的圖形時提供更直觀、更方便的介面,Flutter 還基於這些基礎能力,根據 Material 和 Cupertino 兩種視覺設計風格封裝了一套 UI 元件庫。我們在開發 Flutter 的時候,可以直接使用這些元件庫。
以介面渲染過程為例,和你介紹 Flutter 是如何工作的。
頁面中的各介面元素(Widget)以樹的形式組織,即控制元件樹。Flutter 通過控制元件樹中的每個控制元件建立不同型別的渲染物件,組成渲染物件樹。而渲染物件樹在 Flutter 的展示過程分為四個階段:佈局、繪製、合成和渲染。
佈局(類似Android的onMeasure和onLayout,先確定子View的大小和位置)
Flutter 採用深度優先機制遍歷渲染物件樹,決定渲染物件樹中各渲染物件在螢幕上的位置和尺寸。在佈局過程中,渲染物件樹中的每個渲染物件都會接收父物件的佈局約束引數,決定自己的大小,然後父物件按照控制元件邏輯決定各個子物件的位置,完成佈局過程。
![Flutter核心技術與實戰 04 | Flutter區別於其他方案的關鍵技術是什麼?](https://i.iter01.com/images/92a18e0ffc317e64ebbb6a7ef8952014c66e9abb29cd820fcf64d1bc249a4e89.png)
![Flutter核心技術與實戰 04 | Flutter區別於其他方案的關鍵技術是什麼?](https://i.iter01.com/images/5ea694426b631c2d4f51a74b8200a07432ef5bad4f7ea24d7811e856de497d71.png)
繪製(類似Android的onDraw方法)
佈局完成後,渲染物件樹中的每個節點都有了明確的尺寸和位置。Flutter 會把所有的渲染物件繪製到不同的圖層上。與佈局過程一樣,繪製過程也是深度優先遍歷,而且總是先繪製自身,再繪製子節點。
以下圖為例:節點 1 在繪製完自身後,會再繪製節點 2,然後繪製它的子節點 3、4 和 5,最後繪製節點 6。
![Flutter核心技術與實戰 04 | Flutter區別於其他方案的關鍵技術是什麼?](https://i.iter01.com/images/2e7d011f53902a7779e552216e69c42cc896a71fdc1f06fb894411fa1a3a267e.png)
為了解決這一問題,Flutter 提出了與佈局邊界對應的機制——重繪邊界(Repaint Boundary)。在重繪邊界內,Flutter 會強制切換新的圖層,這樣就可以避免邊界內外的互相影響,避免無關內容置於同一圖層引起不必要的重繪。
![Flutter核心技術與實戰 04 | Flutter區別於其他方案的關鍵技術是什麼?](https://i.iter01.com/images/219d6b756b8e35b5f7f904e199cb0eb6aa91ba3321efb3070830fc9a77943a60.png)
合成和渲染
終端裝置的頁面越來越複雜,因此 Flutter 的渲染樹層級通常很多,直接交付給渲染引擎進行多圖層渲染,可能會出現大量渲染內容的重複繪製,所以還需要先進行一次圖層合成,即將所有的圖層根據大小、層級、透明度等規則計算出最終的顯示效果,將相同的圖層歸類合併,簡化渲染樹,提高渲染效率。
合併完成後,Flutter 會將幾何圖層資料交由 Skia 引擎加工成二維影象資料,最終交由 GPU 進行渲染,完成介面的展示。
![Flutter核心技術與實戰 04 | Flutter區別於其他方案的關鍵技術是什麼?](https://i.iter01.com/images/8fd72d3bd33af8c234cf449cf20c23d0eac75c8c800aed0de626c9389f588e90.jpg)