谈谈flutter的线程
本文同步发布于公众号:移动开发那些事谈谈flutter的线程
刚接触flutter的同学肯定会对fluter所谓的单线程架构很蒙逼,因为这与我们学开发时,各种语言里的多线程的介绍有点出入,而且手机的CPU现在基本都是多核的,操作系统不可能同一时间只在处理一件事件的,
那么flutter究竟是怎样实现 其所谓的单线程架构的呢? 在深入了解flutter的线程架构前,我们先来看看flutter使用的Dart语言的线程模型Isolate
1 Isolate
Isolate是Dart中一种轻量级的执行单元,类似于其他语言的线程,但又比线程更轻量级。其在底层实际还是依赖于操作系统提供的OSThread,与普通的线程的区别在于,Isolate拥有独立的内存,而普通的线程则需要与其他线程共享内存。因此每个Isolate相互独立,有自己单独内存空间(这个更接近于进程),不能在Isolate
之间共享内存。如果两个Isolate之间需要通信,可以通过端口port的方式进行数据的通信。
一个简单的Isolate之间通信的代码为:
// 注册监听
var port = ReceivePort();
IsolateNameServer.registerPortWithName(
port.sendPort, "listen_name_demo");
port.listen((message) {
// 这里去处理接收到的信息
}
// 发送消息
// 名字需要与前面注册的一样
final SendPort? sendPort =
IsolateNameServer.lookupPortByName("listen_name_demo");
if (sendPort != null) {
// 里面的消息的结构,与注册那边保持一致就可(可理解为约定的协议格式)
sendPort.send([id, status.value, progress]);
return;
}
Isolate 之间通过消息传递进行通信的,但 Isolate 内部是怎样对消息进行分发处理的呢?
1.1 内部消息处理
Isolate 内部是通过事件循环和消息队列来实现内部的消息的分发处理的,每个Isolate都会包含两个消息队列和一个事件循环
- Microtask queue: 微任务事件队列,微事件队列的优先级比普通事件队列高
- Event queue: 普通事件队列
- Event Loop: 事件循环,不断在从队列中获取事件进行分发处理,类似于
Android原生的Looper
1.2 异步处理
前面我们了解到Isolate是有消息队列的,但怎样给队列添加异步事件呢?答案是Future
一个简单的添加事件的代码为:
Future.delayed(const Duration(seconds: 3), () {
// 延迟3s后执行的异步操作
});
Future.microtask(() {
// 提交一个异步的微任务
});
而通过关键字Future,async 和 await的结合使用,我们可以把对应的方法变成一个异步的(也等于向普通事件队列里添加一个事件)
// async 说明这是一个异步的方法
Future<T> demoMethod() async {
// 具体的方法名
}
// 在使用的地方可以使用await 等待这个异步方法执行完(不加await说明不用等这个异步方法执行完)
await demoMehtod();
2 线程模型
Flutter所谓的单线程架构是指如果我们不额外创建Isolate的话,它的逻辑都是跑在一个叫做Root的Isolate上,那么这个Isolate是哪里创建呢?
答案就是Embedder(不知道Embedder的同学,可以网上找一张Flutter的架构图看看)。Embedder是Flutter的适配层,用于适配不同的操作系统,负责原生平台插件,
线程管理等功能。Embedder 提供了四个Task Runner
Platform Task Runner:与平台的主线程相对应,用于处理与平台的交互;UI Task Runner:用于执行 Dart 代码,处理 UI 渲染和帧更新(Root Isolate就是运行在这里)。GPU Task Runner:用于执行 GPU 绘制任务。IO Task Runner:用于执行输入/输出任务,如文件读写、网络操作等;
2.1 Platform Task Runner
该Runner运行所有在线程为原生的主线程(也就是我们经常说的UI线程),主要用于:
- 与
FlutterEngine层进行交互 - 处理平台(
Android,iOS,Web等)的消息
尽管是运行在原生的主线程,但在这个Runner里做耗时的操作并不会导致整个应用的卡顿,不过一般也不建议在这里做比较耗时的操作;
2.2 UI Task Runner
该Runner运行所有在线程为原生的子线程,主要用于:
- 执行
Dart代码,也就是执行Root Isolate的逻辑 - 执行渲染与处理
Vsync信号,将Widget转换生成Layer Tree - 处理原生的
Plugin消息 - 定时器,microtasks任务;
2.3 GPU Task Runner
该Runner运行所有在线程为原生的子线程,主要用于:
- 执行
GPU相关的指令; - 将
UI Task生成的Layer Tree转化为GPU可执行的指令;
同样的,虽然是运行在原生的子线程里,但阻塞该线程会引起应用的卡顿,
2.4 IO Task Runner
该Runner运行所有在线程为原生的子线程,主要用于:资源文件相关的处理,如处理图片数据;
3 总结
综上所述,Flutter是通过以下几个部分来实现其线程的管理的:
Isolate及其事件循环和消息队列- 异步处理的语法糖,如
async/await和Future/Stream Embedder提供了四个Task Runner
4参考
公众号

谈谈flutter的线程的更多相关文章
- 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。
windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...
- 谈谈Java的线程池设计
在实际项目中,如果因为想异步执行暂时性的任务而不断创建线程是很浪费资源的事情(当一个任务执行完后,线程也没用了).这种情况下,最好是将任务提交给线程池执行. 所谓池,就是将管理某一种资源,对资源进行复 ...
- Flutter 多引擎支持 PlatformView 以及线程合并解决方案
作者:字节移动技术-李皓骅 摘要 本文介绍了 Flutter 多引擎下,使用 PlatformView 场景时不能绕开的一个线程合并问题,以及它最终的解决方案.最终 Pull Request 已经 m ...
- Flutter异步与线程详解
一:前言 - 关于多线程与异步 关于 Dart,我相信大家都知道Dart是一门单线程语言,这里说的单线程并不是说Dart没有或着不能使用多线程,而是Dart的所有API默认情况下都是单线程的.但大家也 ...
- java 线程的几种状态
java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...
- Java 线程的状态
Java Thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...
- .NET中 类型,对象,线程栈,托管堆在运行时的关系
.NET中 类型,对象,线程栈,托管堆在运行时的关系 The Relationship at Run Time between Types,Objects,A Thread's Stack,and T ...
- [读书心得] .NET中 类型,对象,线程栈,托管堆在运行时的关系
.NET中 类型,对象,线程栈,托管堆 在运行时的关系 The Relationship at Run Time between Types,Objects,A Thread's Stack,and ...
- JAVA中线程的状态
java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW:至今尚未启动的线程的状态. RUNNABLE:可运行线程的线程状态. ...
- 【转】java 线程的几种状态
java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...
随机推荐
- Docker-compose 常用命令和模板
docker-compose logs -f ##查看该容器的启动的日志打印(日志从头打印 docker logs -f container_id ##查看某一容器的启动的日志打印(日志从头打印) d ...
- Jenkins Job触发其他远程Job
https://blog.csdn.net/diaojian66/article/details/117334537 如果不想遇到连接远程Jenkins主机失败后的反复尝试,去掉认证会是一个不错的选择 ...
- 使用 ollama 在本地试玩 LLM
在 chatGPT 的推动下.LLM 简直火出天际,各行各业都在蹭.听说最近 meta 开源的 llama3 模型可以轻松在普通 PC 上运行,这让我也忍不住来蹭一层.以下是使用 ollama 试玩 ...
- Windows安装Mysql后一段时间后Mysql服务无法启动的问题
本人在windows重装电脑后遇到一个比较麻烦的问题一直没有解决,今日有幸看到某大佬的博客得以解决.真实万分感激,特来分享一下. 第一次安装Mysql8.0之后,此次安装是将整个mysql包进行安装, ...
- 【鸣潮,原神PC端启动器】仿二次元手游PC端游戏启动器,以鸣潮为例。
二游GAMELanucher启动器 1.前言 许多二次元手游(原神,鸣潮,少女前线)的PC端启动器都是使用Qt做的,正好最近正在玩鸣潮,心血来潮,便仿鸣潮启动器,从头写一个.先下载一个官方版的PC启动 ...
- 性能调优、虚拟机、垃圾回收、软硬件协调相关文章和视频 — Part1
本文由 ImportNew - 顾星竹 翻译自 javacodegeeks.如需转载本文,请先参见文章末尾处的转载要求. ImportNew注:如果你也对Java技术翻译分享感兴趣,欢迎加入我们的 J ...
- AbstractQueuedSynchronizer源码解析之ReentrantLock(二)
上篇文章分析了ReentrantLock的lock,tryLock,unlock方法,继续分析剩下的方法,首先开始lockInterruptibly,先看其API说明:lockInterruptibl ...
- Python:编程“八荣八耻”之我见
刚在逛CPyUG时看到了个主题讨论python的八荣八耻,见:http://bit.ly/4jeBor, 主题内容如下: 以动手实践为荣,以只看不练为耻. 以打印日志为荣,以单步跟踪为耻. 以空白 ...
- python之pyexecjs
pyexecjs是一个用Python来执行JavaScript代码的工具库,该库支持多种JavaScript运行时环境,如Node.js.PhantomJS.SlimerJS等,允许开发者在Pytho ...
- Windows系统安装使用Scoop包管理器
前言 Scoop是Windows的命令行安装程序. 如果用过Linux系统,使用apt-get工具安装过软件,或者用过Python,知道pip工具用于管理Python各种依赖包,那么理解Sco ...