Flutter 核心技术与实战
陈航
前美团点评高级技术专家
42432 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 48 讲
Flutter 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

23 | 单线程模型怎么保证UI运行流畅?

在Flutter中,借助UI框架提供的事件循环,不需要开多线程
异步与多线程并不是同等关系
2. 改造代码,实现输出结果为f1、f2、f3、f4
1. 为什么在asyncFactoriali方法里先后发给了并发Isolate两个SendPort?能否只发一个SendPort?
compute函数封装Isolate的创建和结果的返回
通过消息机制进行单向通信
Dart中的多线程机制
借助await与async实现非阻塞的同步等待
Future是异步任务的封装
Dart通过事件循环实现异步
总结
思考题
Isolate
Dart是单线程的
Dart的异步与并发机制

该思维导图由 AI 生成,仅供参考

你好,我是陈航。
在上一篇文章中,我带你一起学习了如何在 Flutter 中实现动画。对于组件动画,Flutter 将动画的状态与渲染进行了分离,因此我们需要使用动画曲线生成器 Animation、动画状态控制器 AnimationController 与动画进度监听器一起配合完成动画更新;而对于跨页面动画,Flutter 提供了 Hero 组件,可以实现共享元素变换的页面切换效果。
在之前的章节里,我们介绍了很多 Flutter 框架出色的渲染和交互能力。支撑起这些复杂的能力背后,实际上是基于单线程模型的 Dart。那么,与原生 Android 和 iOS 的多线程机制相比,单线程的 Dart 如何从语言设计层面和代码运行机制上保证 Flutter UI 的流畅性呢?
因此今天,我会通过几个小例子,循序渐进地向你介绍 Dart 语言的 Event Loop 处理机制、异步处理和并发编程的原理和使用方法,从语言设计和实践层面理解 Dart 单线程模型下的代码运行本质,从而懂得后续如何在工作中使用 Future 与 Isolate,优化我们的项目。

Event Loop 机制

首先,我们需要建立这样一个概念,那就是 Dart 是单线程的。那单线程意味着什么呢?这意味着 Dart 代码是有序的,按照在 main 函数出现的次序一个接一个地执行,不会被其他代码中断。另外,作为支持 Flutter 这个 UI 框架的关键技术,Dart 当然也支持异步。需要注意的是,单线程和异步并不冲突。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Dart语言的异步与并发机制是Flutter开发中的关键技术,本文深入介绍了Dart单线程模型下的代码运行本质以及如何在工作中使用Future与Isolate优化项目。通过讲解Dart语言的Event Loop处理机制、异步处理和并发编程的原理和使用方法,读者可以深入了解Flutter开发技术。文章强调了异步与多线程的区别,以及在UI编程过程中的应用。此外,文章还提出了两道思考题,引发读者思考与讨论。整体而言,本文适合想要深入了解Flutter开发技术的读者阅读。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Flutter 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(57)

  • 最新
  • 精选
  • jerry
    您好老师,单线程模型是指的事件队列模型,和绘制界面的线程是一个吗

    作者回复: 我们所说的单线程指的是主Isolate。而GPU绘制指令有单独的线程执行,跟主Isolate无关。事实上Flutter提供了4种task runner,有独立的线程去运行专属的任务: 1.Platform Task Runner:处理来自平台(Android/iOS)的消息 2.UI Task Runner:执行渲染逻辑、处理native plugin的消息、timer、microtask、异步I/O操作处理等 3.GPU Task Runner:执行GPU指令 4.IO Task Runner:执行I/O任务 除此之外,操作系统本身也提供了大量异步并发机制,可以利用多线程去执行任务(比如socket),我们在主Isolate中无需关心(如果真想主动创建并发任务也可以)

    2019-10-29
    22
  • Geek_keyi
    对Dart单线程模型理解还是迷惑,请教一下:假如有一个任务(读写文件或者网络)耗时10秒,并且加入到了事件任务队列中,执行单这个任务的时候不就把线程卡主吗?

    作者回复: 文件I/O和网络调用并不是在Dart层做的,而是由操作系统提供的异步线程,他俩把活儿干完之后把结果刚到队列中,Dart代码只是执行一个简单的读动作。

    2019-09-25
    6
    15
  • 吴小安
    现在手机都是多核,使用future执行异步任务都是放在当前线程,而要在其他线程执行就要这么麻烦,这样大部分人写的异步任务都发挥不了多核的性能,是不是有点浪费?

    作者回复: 无需担心,我们说的单线程其实是针对主Isolate的。事实上Flutter提供了4种task runner,他们有独立的线程去运行专属的任务: 1.Platform Task Runner:处理来自平台(Android/iOS)的消息 2.UI Task Runner:执行渲染逻辑、处理native plugin的消息、timer、microtask、异步I/O操作处理等 3.GPU Task Runner:执行GPU指令 4.IO Task Runner:执行I/O任务 这些特定任务的执行都是固定的套路,另外操作系统本身也提供了大量异步并发机制,可以利用多线程去执行任务(比如socket),我们在主Isolate中无需关心(如果真想主动创建并发任务也可以),因此说基于主Isolate的Flutter是单线程模型的。

    2019-08-21
    3
    4
  • Geek_20f143
    Future(() => print('a1')) .then((_) { Future(() => print('a2')); }).then((_) => print('a3')); Future(() => print('a1')) .then((_) => Future(() => print('a2'))) .then((_) => print('a3')); 老师,为什么第一部分打印顺序是a1 a3 a2... 第二部分打印顺序是a1 a2 a3 a2区别那部分不是只是语法糖吗?

    作者回复: 你把第一个语句的then加个return再试试 Future(() => print('a1')) .then((_) { return Future(() => print('a2')); }).then((_) => print('a3'));

    2019-12-10
    3
  • 菜头
    1、因为两个 SendPort 的作用不一样 第一个 SendPort 是为了让并发 Isolate 回传一个 SendPort 第二个 SendPort 是为了让并发 Isolate 回传结果 可以改造成一个 监听第一个 SendPort 的回调,根据结果类型复用这个 SendPort 并且在计算结果完成之后关掉 SendPort 即可

    作者回复: 可以的,赞👍

    2019-11-19
    3
    3
  • GGL
    // 第一段 Future(() => print('f6')) .then((_) => Future(() => print('f7'))) .then((_) => print('f8')); 执行结果为:f6 f7 f8 // 第二段 Future(() => print('f6')) .then((_) { Future(() => print('f7')); }) .then((_) => print('f8')); 执行结果为:f6 f8 f7 老师,上面这两段代码为什么执行结果不一样呢?

    作者回复: 单行箭头函数是Future,和函数体里有Future不是一回事

    2019-11-03
    7
    2
  • 楼外楼
    Dart 中的 await 并不是阻塞等待,而是异步等待,这句话是不是有问题,await 就是阻塞后面代码执行,等待异步代码返回。难道我理解有误?

    作者回复: await阻塞的是当前上下文的后续代码执行,并不能阻塞其调用栈上层的后续代码执行

    2019-08-30
    2
  • lk
    Future(() => print('f1')) .then((_) async => scheduleMicrotask(() => print('f2'))) .then((_) => print('f3')); Future(() => print('f4'));

    作者回复: 赞👍另外建议把await加上

    2019-08-29
    2
  • 满大大
    await 的上下文函数并不包含调用栈,因此 func 后续代码继续执行,打印“func after”。这里怎么理解?

    作者回复: 就是await只等待当前的语句,并不是以把整个调用栈都锁死的方式进行等待。

    2019-12-06
    1
  • Geek_869250
    老师可以和JS的event loop做个比较吗

    作者回复: 基本上一样,因为Dart的单线程模型就是借鉴的js

    2019-10-28
    2
    1
收起评论
显示
设置
留言
57
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部