今日頭條 Flutter 架構實踐

iOS面試簡歷專員發表於2020-04-16

移動跨平臺技術探究


◆ 為什麼需要跨平臺?


今日頭條 Flutter 架構實踐

◆ 跨平臺技術是如何發展起來的?


今日頭條 Flutter 架構實踐

◆ 跨平臺技術選型有哪些?


今日頭條 Flutter 架構實踐


◆ Flutter有什麼獨特優勢(為什麼選擇Flutter)?


今日頭條 Flutter 架構實踐

◆ 為什麼說Flutter是高效能的,體現在哪裡?


今日頭條 Flutter 架構實踐

Flutter引擎原理剖析


先來看看Flutter的技術架構圖:


C++引擎四個核心執行緒


Flutter 裡四個核心執行緒:平臺執行緒、UI 執行緒、GPU 執行緒、IO 執行緒,它們的職責都是不一樣的:


★ 平臺執行緒(PlatformThread)對應著安卓和 iOS 的主執行緒。


★ UI執行緒(UI Thread)針對安卓本身的主執行緒,它就是一個獨立的執行緒。


★ GPU執行緒(GPU Thread)執行在 GPU 上的執行緒,它主要是處理 Skia 相關的任務。


★ IO執行緒(IO Thread)主要處理IO有關的任務,比如:圖片編解碼等。


具體引擎架構圖,如下圖示所示:


今日頭條 Flutter 架構實踐

Flutter如何編譯成兩個平臺的應用程式


今日頭條 Flutter 架構實踐

首先看下面的引擎程式碼是公共的部分,用於把程式的原始碼編譯Android和IOS兩個平臺的應用程式。中間左側綠色部分Flutter針對Android生成的一些檔案,然後最終透過引擎會編譯生成Android的APK安裝包,中間右側藍色部分是Flutter針對IOS平臺生成的一些檔案,然後最終透過引擎會編譯會生成IOS平臺的安裝包。


執行緒通訊(混合開發必須瞭解的難點)


今日頭條 Flutter 架構實踐

這裡以Android為例,對照Flutter做一個講解。Flutter裡面的執行緒主要依賴於Dart裡面的一些API,比如我們常用的非同步任務裡面,需要用到:MicroTask和Future,就是非常重要和關鍵的。


我們可以看到技術是相通的,Android裡面是一個Handler,對應一個Looper Thread,然後是一個MessageQueue,然後裡面存放的是Message。很巧妙的是Flutter也有類似的做法,Flutter有一個Looper執行緒,主執行緒複用了Native的,然後為其他三個執行緒建立獨立的Looper。不過與Android不同的是:Flutter用的是兩個佇列,一個是微任務佇列(MicroTaskQueue),一個是普通延遲任務佇列。Flutter會先處理為任務佇列,再去處理普通任務佇列。類比Android來講,圖中的TaskRunner類似於Handler,PostTask就是把一個訊息放到一個訊息佇列的過程。和Android的Handler是很類似的。所以在學新技術的時候,舉一反三,懂得變通才能學的更好。


Dart虛擬機器


同一個程式裡可以有很多 Isolate,兩個 Isolate 的堆是不能共享的。Dart開發團隊早就考慮到了互動的問題,於是就設計了一個VM Isolate,它是一個使用者Isolate之間互動的橋樑,執行在 UI 執行緒中的。我們可以把資料放在核心態,因為這個核心態可以共享資料,然後把資料放到另一方的佇列中,另一方就可以拿到和使用這些資料了。熟悉Android的朋友們應該聽起來很熟悉,這就非常類似我們熟知的“程式間通訊”。


今日頭條 Flutter 架構實踐

可能這樣講還不是很清楚,具體流程是什麼樣的呢?請看下圖:


今日頭條 Flutter 架構實踐

Isolate1是傳送方,建立一個SendPort ,Isolate2是接收方,建立一個ReceivePort。我們建立一個 Isolate的時候,它裡面有一個 worker 執行緒,worker 執行緒裡面可以放入Task。SendPort呼叫send方法,傳送資料到PortMap裡面,這個裡面每一個port對應一個Isolate 的 MessageHandler,這個Handler包括兩個內容:普通的訊息佇列,一個是 OOB 高優先順序訊息,資料放入佇列順序有優先順序區分。最後訊息被封裝成一個 MessageTask,傳送到另一個Isolate裡面去。回想一下是不是類似於Android的訊息佇列?


Platform Channels


今日頭條 Flutter 架構實踐

Flutter提供了Channel是用於和Native功能做互動。Android這邊使用MethodChannel,IOS這邊使用FlutterMethdChannel。最終Flutter透過銜接兩個平臺,使用統一的規範去銜接兩個平臺,暴露出一些函式和介面,然後就可以很容易的使用Flutter去呼叫Native的功能了。這個依賴於開發者的水平,需要對Android或IOS比較瞭解才能更好的寫出外掛出來。pub.dev上面也有很多開源庫,不過往往開發中需求總是在變更的,開源庫遠遠達滿足不了實際開發需求的功能點,所以還是需要自己掌握Platform Channels的知識點比較好。


位元組跳動在Flutter架構上的實踐


下面來看位元組跳動主要做了哪些架構實踐,請看下圖:


今日頭條 Flutter 架構實踐

從上圖中還是可以看到位元組跳動做了很多基礎工作的,比如:容器化、混合工程、渲染、包體積、編譯最佳化、多端一體化等。看上去確實感覺是很多東西的。下面簡單的介紹其中比較關鍵的幾個:


容器化架構


今日頭條 Flutter 架構實踐

個人感覺所謂“容器化”,就類似於原生平臺的元件化或者業務分層架構的思想。就是為普通業務打造可擴充套件的介面和行為準則。不過這個Flutter容器化架構要適應Android和IOS兩個平臺,然後針對不同的平臺的業務行為需要定義統一的標準和規範以及封裝了一些通用業務模組功能(其中的某些可以看做是基礎業務的基類),比如:圖片呼叫,直接去這裡面的協議層,直接呼叫就可以了,內部都封裝好了,直接傳參呼叫,這裡面有預設的適配,你也可以自定義。有了“容器化”的架構,平臺基礎API的差異性就不需要考慮了,開發者只管呼叫內部的功能模組或者介面即可快速開發新需求功能。


多端一體化實踐


今日頭條 Flutter 架構實踐

這個就不用多說了,就是寫一個應用可以同時執行在Android、IOS、Web上面,省去了大量的開發週期,多端一體化結合了Flutter,以及Flutter Web,然後定製化了一些內部引擎和功能模組的架構,最終打造出了這套多端一體化的工程體系架構。


監控體系


今日頭條 Flutter 架構實踐

Flutter自帶的效能監控工具顆粒度是很粗糙的,用的是物理平均,而不能反映真實的每一幀實時統計。UI執行緒和GPU執行緒的處理方式不一樣,這樣物理平均確實是不直觀的做法。


業界很多公司通用的做法是框架層去統計UI執行緒耗時時間,訊息 post 到 UI,然後再post到GPU。但是這種做法有兩個缺陷:一個是等待時間沒有考慮進去,一個是UI 執行緒非常快,但是 GPU 執行緒非常慢,UI 執行緒向 GPU 執行緒跑訊息時最多 Post 兩個訊息,這時候 GPU 執行緒依然處理不過來,UI 執行緒就不會 Post 訊息,但是 UI 執行緒體現不出來。


位元組跳動採用的是“高精度無侵入效能監控方案”:引擎層提供了一套機制,可以知道繪製多少幀,統計你發了多少訊號,統計 GPU 執行緒。另外“無侵入”體現在:框架系統會自動識別效能監控滾動會在什麼時候開始,什麼時候結束。


Flutter Turbo


今日頭條 Flutter 架構實踐

這個主要是效能提升的方案,比如:訊息排程、GC抑制、關閉Semantics、關閉抗鋸齒等,另外為了提高效能,內部有一個 Benchmark 跑分,有了這些方案支援,可以大大的提升應用程式額效能。


圖片透傳最佳化方案


今日頭條 Flutter 架構實踐

我個人覺得這個方案還是挺不錯的,非常有借鑑價值,值得學習和研究一下。現有的方式 Image.network載入網路圖片,傳入一個路徑就可以載入了,然後Dart底層引擎層做解碼操作。另外外接紋理方案也是不錯的,也是可以實現的,但是它沒有在這個基礎上進行改造,效能上還有提升空間。位元組跳動的透傳方案是這樣的:使用框架載入圖片,然後生成Bitmap,然後Native和Dart VM共享Bitmap,而不是直接的資料傳過來的,然後Dart引擎再轉成Pixel buffer,這樣一來對效能有很大的提升。包體積最佳化


今日頭條 Flutter 架構實踐

大概有這些最佳化:做了編譯最佳化;對Flutter產物的資料端做了壓縮,對Skia做了裁剪,不需要的東西刪掉了,引擎庫對一些功能三方庫也做了裁剪。


【雖說看的雲裡霧裡,感覺還是很厲害的樣子。型別一萬個:“臥槽,這麼牛逼!”】


今日頭條 Flutter 架構實踐

在這次會議上的第3個主題演講中,來自位元組跳動的專家還專門對包體積最佳化做了講解,我會在後面的文章再整理一下分享給大家。


啟動速度最佳化


修改了引擎程式碼,對啟動速度做了最佳化,幾乎提升了1倍。


推薦?:


如果你想一起進階,不妨新增一下交流群[1012951431](%3A%2F%2Fjq.qq.com%2F%3F_wv%3D1027%26k%3D5JFjujE)


面試題資料或者相關學習資料都在群檔案中 進群即可下載!


今日頭條 Flutter 架構實踐


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69971523/viewspace-2686559/,如需轉載,請註明出處,否則將追究法律責任。

相關文章