深刻了解Flutter的isolate(3) --- Flutter的thread model(線程模型)

0x00 前言

Flutter中有一個很重要的概念就是isolate,isolate是由一個線程實現的,實現isolate的線程由Flutter建立和管理,除了實現isolate的線程,Flutter還有其他的線程,本篇文章探討Flutte的threading model(線程模型)。android

0x01 Flutter Architecture overview

從圖中能夠看出Flutter有3部分組成:

  1. Framework(Dart):咱們在寫Flutter應用中,直接接觸的
  2. Engine(C/C++):引擎層,提供核心技術,例如:Skia(2D圖形渲染庫);Dart(一個用於垃圾收集的面嚮對象語言的VM,DartVM有本身的線程池);shell(不一樣的平臺有不一樣的shell,例若有Android和iOS的shell)
  3. Embedder(Platform Specific):嵌入層,爲Engine建立和管理線程,做用是把Engine的task runners(任務運行器) 運行在嵌入層管理的線程上。

0x02 Flutter的task runners的分類

上面講了task runners要運行的線程上,這裏的task runners有四種,並且都是運行在不一樣的線程上(能夠運行在同一個線程上,可是出於性能的因素,不建議這麼作)。shell

task runners分爲四種:架構

  1. Platform Task Runner
  2. UI Task Runner
  3. GPU Task Runner
  4. IO Task Runner

1. Platform Task Runner

  • Platform Task Runner運行所在的線程 對應 平臺的線程異步

    Android iOS
    主線程 主線程
  • 功能 嵌入層和Engine層的交互,處理平臺(Android/iOS)的消息socket

  • 爲何必定要是平臺的主線程? 由於Platform Task Runner的功能是要處理平臺的消息,可是平臺的API都是隻能在主線程調用,因此Platform Task Runner運行所在的平臺的線程必須是主線程oop

  • 一個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運行所在的線程 對應到 平臺的線程orm

    Android iOS
    子線程 子線程

    這裏很容易讓你們誤會,由於一看名字,UI Task Runner,第一反應,UI ? 那確定是在主線程裏的,其實並非,UI Task Runner運行所在的線程 對應到 平臺的線程,實際上是子線程cdn

  • 功能

    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任務運行器使用相同的主線程。

相關文章
相關標籤/搜索