0x00 前言
Flutter中有一個很重要的概念就是isolate,isolate是由一個執行緒實現的,實現isolate的執行緒由Flutter建立和管理,除了實現isolate的執行緒,Flutter還有其餘的執行緒,本篇文章探討Flutte的threading model(執行緒模型)。
0x01 Flutter Architecture overview
從圖中可以看出Flutter有3部分組成:- Framework(Dart):我們在寫Flutter應用中,直接接觸的
- Engine(C/C++):引擎層,提供核心技術,例如:Skia(2D圖形渲染庫);Dart(一個用於垃圾收集的面嚮物件語言的VM,DartVM有自己的執行緒池);shell(不同的平臺有不同的shell,例如有Android和iOS的shell)
- Embedder(Platform Specific):嵌入層,為Engine建立和管理執行緒,作用是把Engine的task runners(任務執行器) 執行在嵌入層管理的執行緒上。
0x02 Flutter的task runners的分類
上面講了task runners要執行的執行緒上,這裡的task runners有四種,而且都是執行在不同的執行緒上(可以執行在同一個執行緒上,但是出於效能的因素,不建議這麼做)。
task runners分為四種:
- Platform Task Runner
- UI Task Runner
- GPU Task Runner
- IO Task Runner
1. Platform Task Runner
-
Platform Task Runner執行所在的執行緒 對應 平臺的執行緒
Android iOS 主執行緒 主執行緒 -
功能 嵌入層和Engine層的互動,處理平臺(Android/iOS)的訊息
-
為什麼一定要是平臺的主執行緒? 因為Platform Task Runner的功能是要處理平臺的訊息,但是平臺的API都是隻能在主執行緒呼叫,所以Platform Task Runner執行所在的平臺的執行緒必須是主執行緒
-
一個Flutter Engine對應一個Platform Thread(一個Flutter應用啟動的時候會建立一個Engine例項,Engine建立的時候會建立一個Platform執行緒供Platform Task Runner使用)
-
阻塞Platform Thread不會直接導致Flutter應用的卡頓(跟iOS android主執行緒不同)。儘管如此,也不建議在這個Runner執行繁重的操作,長時間卡住Platform Thread應用有可能會被系統Watchdog強殺。
2. UI Task Runner
-
UI Task Runner執行所在的執行緒 對應到 平臺的執行緒
Android iOS 子執行緒 子執行緒 這裡很容易讓大家誤會,因為一看名字,UI Task Runner,第一反應,UI ? 那肯定是在主執行緒裡的,其實並不是,UI Task Runner執行所在的執行緒 對應到 平臺的執行緒,其實是子執行緒
-
功能
1)用於執行Dart root isolate程式碼
2)渲染邏輯,告訴Engine最終的渲染
3)處理來自Native Plugins的訊息
4)timers
5)microtasks
6)非同步 I/O 操作(sockets, file handles, 等)
-
Root isolate就是執行在這個執行緒上,所以isolate就可以理解為單執行緒,有event loop的架構
-
阻塞這個執行緒會直接導致Flutter應用卡頓掉幀
-
為了防止阻塞這個執行緒,我們可以建立其他的isolate,建立的isolate沒有繫結Flutter的功能,只能做資料運算,不能呼叫Flutter的功能,而且建立的isolate的生命週期受Root isolate控制,Root isolate停止,其他的isolate也會停止,而且建立的isolate執行的執行緒,是DartVM裡的執行緒池提供的
3.GPU Task Runner
-
GPU Task Runner執行所在的執行緒 對應到 平臺的執行緒
Android iOS 子執行緒 子執行緒 -
功能
GPU Task Runner主要用於執行裝置GPU的指令。在UI Task Runner 建立layer tree,在GPU Task Runner將Layer Tree提供的資訊轉化為平臺可執行的GPU指令。
-
UI Task Runner和GPU Task Runner跑在不同的執行緒。GPU Runner會根據目前幀執行的進度去向UI Task Runner要求下一幀的資料,在任務繁重的時候可能會告訴UI Task Runner延遲任務。這種排程機制確保GPU Task Runner不至於過載,同時也避免了UI Task Runner不必要的消耗。
-
在此執行緒耗時太久的話,會造成Flutter應用卡頓,所以在GPU Task Runner儘量不要做耗時的任務,例如載入圖片的時候,去讀取圖片資料,就不應該放在GPU Task Runner,而是放在接下來要講的IO Task Runner
-
建議為每一個Engine例項都新建一個專用的GPU Task Runner執行緒。
4. IO Task Runner
-
IO Task Runner執行所在的執行緒 對應到 平臺的執行緒
Android iOS 子執行緒 子執行緒 -
功能
1)主要功能是從圖片儲存(比如磁碟)中讀取壓縮的圖片格式,將圖片資料進行處理為GPU Runner的渲染做好準備。IO Runner首先要讀取壓縮的圖片二進位制資料(比如PNG,JPEG),將其解壓轉換成GPU能夠處理的格式然後將資料上傳到GPU。 2)載入其他資原始檔
-
在IO Task Runner不會阻塞Flutter,雖然在載入圖片和資源的時候可能會延遲,但是還是建議為IO Task Runner單獨開一個執行緒。
0x03 各個平臺的執行緒配置
1.iOS
為每個引擎例項的UI,GPU和IO任務執行程式建立專用執行緒。所有引擎例項共享相同的Platform Thread和Platform Task Runner。
2.Android
為每個引擎例項的UI,GPU和IO任務執行程式建立專用執行緒。所有引擎例項共享相同的Platform Thread和Platform Task Runner。
3.Fuchsia
每一個Engine例項都為UI,GPU,IO,Platform Runner建立各自新的執行緒。
4.Flutter Tester (used by flutter test)
UI,GPU,IO和Platform任務執行器使用相同的主執行緒。