深刻了解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任务运行器使用相同的主线程。

相关文章
相关标签/搜索