Flutter 在全新 Platform 和 UI 线程合并后,出现了什么大坑和变化?

news2025/4/25 10:59:51

Flutter 在全新 Platform 和 UI 线程合并后,出现了什么大坑和变化?

在两个月前,我们就聊过 3.29 上《Platform 和 UI 线程合并》的具体原因和实现方式,而事实上 Platform 和 UI 线程合并,确实为后续原生语言和 Dart 的直接同步调用打了一个良好基础,在《Flutter Roadmap 2025》 里官方也提到了:

直接从 Dart 调用 Objective C 和 Swift 代码(适用于 iOS)以及 Java 和 Kotlin(适用于 Android),2025 这种同步调用方式也许可以在 Framework 和 Plugin 层面大规模引入。

没有 MethodChannel 确实是好事,但是凡事皆有利弊,线程合并随着也带来了它的一些负面问题,首先最直观的就是,在 Android 断点开发时,断点 Dart 代码现在会导致 ANR 弹框:

其实这可以理解,因为现在 Dart 和平台主线程绑定在一起了,断点导致的无响应而出现 ANR 很合理,如果比较介意,而目前解决的办法也很简单,就是暂时关了线程合并,你可以选择的 Debug 的 AndroidManifest 关闭线程合并:

        <meta-data
            android:name="io.flutter.embedding.android.DisableMergedPlatformUIThread"
            android:value="true" />

那如果说上面这只是小问题,那么下面这个可以说是比较关键的问题了。

在 #163064 里,因为线程合并之后,启动引擎、应用和设置 Dart 代码都运行的平台线程上,会导致第一个可交互帧的时间变长,并且还看具体场景:

特别是,当平台线程在 Android (例如 Android Activity 的布局)和 Dart 执行工作之间分配时,就可能会有更多的延迟。

这其实也是可预见的情况,在合并线程这个 feature 提出来时,就有人担忧类似问题,而解决办法也很“简单”,那就是启动的时候多加一个启动线程:

所以,一个新功能修复了老 Bug,但是总会带来好几个新的 Bug ,所以两 issue 生四翔,四翔生 Bug 挂。

目前 #166918 这个 PR 已经成功合并,该 PR 将原本的简单 bool 合并线程启用状态修改为三种线程状态,其中就有全新的 kMergeAfterLaunch :

kMergeAfterLaunch 模式下,Engine 会在单独的 Dart UI 线程上启动引擎,然后在引擎初始化后会将 UI 任务移至平台线程合并,从而改善应用启动延迟的问题。

简单说,就是启动时还是走老的 Dart UI 线程,启动完成之后再合并到一起。

在启动之前,引擎通过设置让 root isolate 关联到原本的 UI Runner ,从而实现单独的启动线程:

而在启动之后,Dart 的主线程就会移动到平台线程,虽然说是“移动线程”,但是通过上面的代码我们可以看到,实际上就是将两个任务队列 Merge 合并成一个,也就是原本分别在两个任务队列中排队的任务,启动成功后会被放入同一个队列中,并由同一个线程来执行。

我们之前就讲过,UI Runner 都是通过独立的 MessageLoopTaskQueues 来处理任务,而 MessageLoopTaskQueues 又是 Flutter Engine 内部用于管理任务队列的类,它负责创建、维护和调度任务队列。

因为 Flutter Engine 不会直接控制线程的创建和销毁,而是通过控制任务队列的调度来间接影响线程的行为,通过合并任务队列,Engine 就可以让多个线程执行的任务集中到一个线程上,从而达到合并线程的作用。

而对应的还有 Unmerge 操作,Unmerge 会将之前合并的任务队列重新分离成两个独立的队列,这样在 Engine 需要关闭或者销毁的时候,就可以将合并的线程恢复到原始状态。

另外,目前在 kMergeAfterLaunch 模式下,禁止生成共享相同任务运行器的引擎,因为在线程合并后,生成新的引擎可能会导致死锁:

所以可以看到,增加启动线程的核心就是用原本的 Dart UI 线程进行启动,然后启动完成把任务队列合并到平台线程,回归平台线程的逻辑。

当然,说起来简单,事实上这个修改在 Engine 涉及了 36 个文件,所以会不会改出什么新的 bug,暂时不好评价:

另外,目前 maoOS 的线程合并也已经完成,所以下个版本开始 macOS 上也是统一的平台线程支持了,有了这个,似乎在 macOS 上使用 FFI 制作自己的图形 API 也不是不可能:

最后,顺带一提,Flutter 官方正式启动了 Widget 预览的开发推进,只是从我的角度,总觉得这个没太大必要,毕竟感觉就算出来了也不会很好用:

所以,你在 Flutter 3.29 上还有遇到过什么线程合并带来的问题吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2342362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

stm32之GPIO函数详解和上机实验

目录 1.LED和蜂鸣器1.1 LED1.2 蜂鸣器 2.实验2.1 库函数&#xff1a;RCC和GPIO2.1.1 RCC函数1. RCC_AHBPeriphClockCmd2. RCC_APB2PeriphClockCmd3. RCC_APB1PeriphClockCmd 2.1.2 GPIO函数1. GPIO_DeInit2. GPIO_AFIODeInit3. GPIO_Init4. GPIO_StructInit5. GPIO_ReadInputDa…

用 PyQt5 和 asyncio 打造接口并发测试 GUI 工具

接口并发测试是测试工程师日常工作中的重要一环&#xff0c;而一个直观的 GUI 工具能有效提升工作效率和体验。本篇文章将带你用 PyQt5 和 asyncio 从零实现一个美观且功能实用的接口并发测试工具。 我们将实现以下功能&#xff1a; 请求方法选择器 添加了一个下拉框 QComboBo…

Qt实战之将自定义插件(minGW)显示到Qt Creator列表的方法

Qt以其强大的跨平台特性和丰富的功能&#xff0c;成为众多开发者构建图形用户界面&#xff08;GUI&#xff09;应用程序的首选框架。而在Qt开发的过程中&#xff0c;自定义插件能够极大地拓展应用程序的功能边界&#xff0c;让开发者实现各种独特的、个性化的交互效果。想象一下…

【Vue】TypeScript与Vue3集成

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Vue 文章目录 1. 前言2. 环境准备与基础搭建2.1. 安装 Node.js 与 npm/yarn/pnpm2.2. 创建 Vue3 TypeScript 项目2.2.1. 使用 Vue CLI2.2.2. 使用 Vite&#xff08;推荐&#xff09;2.2.3. 目录结构简述 3. Vue3 TS 基础语法整…

Linux之七大难命令(The Seven Difficult Commands of Linux)

Linux之七大难命令 、背景 作为Linux的初学者&#xff0c;肯定要先掌握高频使用的指令&#xff0c;这样才能让Linux的学习在短时间内事半功倍。但是&#xff0c;有些指令虽然功能强大&#xff0c;但因参数多而让初学者们很害怕&#xff0c;今天介绍Linux中高频使用&#xff0…

5.3.1 MvvmLight以及CommunityToolkit.Mvvm介绍

MvvmLight、CommunityToolkit.Mvvm是开源包,他们为实现 MVVM(Model-View-ViewModel)模式提供了一系列实用的特性和工具,能帮助开发者更高效地构建 WPF、UWP、MAUI 等应用程序。 本文介绍如下: 一、使用(旧)的MvvmLight库 其特点如下,要继承的基类是ViewModelBase;且使用…

Dbeaver 执行 SQL 语句和执行 SQL 脚本的区别

执行 SQL 语句 执行 SQL 语句对应图标&#xff1a; 适用于执行单个 SQL 的情形&#xff0c;默认是在光标处或选中的文本上执行 SQL 查询。 实际上同时选择多个 SQL 并通过该方式去执行也可能成功&#xff0c;只是有失败的风险。因此不建议使用它来同时执行多个 SQL 语句。 情况…

《Python3网络爬虫开发实战(第二版)》配套案例 spa6

Scrape | Moviehttps://spa6.scrape.center/ 请求影片列表api时&#xff0c;不仅有分页参数&#xff0c;还多了一个token&#xff0c;通过重发请求发现token有时间限制&#xff0c;所以得逆向token的生成代码。 通过xhr断点定位到接口请求位置 刷新页面或者点翻页按钮&#x…

Python基础语法:字面量,注释,关键字,标识符,变量和引用,程序执行的3大流程

目录 字面量&#xff08;数据的类型&#xff09; 字面量的含义 常见字面量类型&#xff08;6种&#xff09; 输出各类字面量&#xff08;print语句&#xff09; 注释&#xff08;单行和多行注释&#xff09; 注释的作用 单行注释和多行注释 单行注释&#xff08;ctrl/&a…

SPL 量化 获取数据

下载数据 我们将股票数据分享在百度网盘上供下载&#xff0c;每工作日更新。 目前可供下载的数据有 A 股的日 K 线数据、股票代码列表和上市公司的基本面数据 下载链接&#xff1a; 百度网盘 下载数据的文件格式为 btx&#xff0c;是 SPL 的特有二进制格式。 btx 称为集文…

Rust 学习笔记:安装 Rust

Rust 学习笔记&#xff1a;安装 Rust Rust 学习笔记&#xff1a;安装 Rust在 Windows 上安装 Rust命令行创建 Rust 项目在 Mac/Linux 上安装 Rust一些命令升级卸载cargo -hrustc -h 安装 RustRoverrust-analyzer Rust 学习笔记&#xff1a;安装 Rust 在 Windows 上安装 Rust …

编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)

前言 在使用终端编译 C 程序时&#xff0c;报错&#xff1a; 或类似提示&#xff0c;意味着你的系统尚未正确安装或配置 g 编译器。本篇将从零手把手教你在 Windows / Linux / macOS 下安装并配置 g&#xff0c;适用于新手或 C 入门阶段的你。 什么是 g&#xff1f; g 是 GN…

html单页业务介绍源码

源码介绍 html单页业务介绍源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行 效果预览 源码免费获取 html单页业务介绍源码

单体OJ项目

单体项目版本、微服务版还需我再钻研钻研。 项目介绍 在系统前台&#xff0c;管理员可以创建、管理题目;用户可以自由搜索题目、阅读题目、编写并提交代码。 在系统后端&#xff0c;能够根据管理员设定的题目测试用例在代码沙箱 中对代码进行编译、运行、判断输出是否正确。 其…

豆包桌面版 1.47.4 可做浏览器,免安装绿色版

自己动手升级更新办法&#xff1a; 下载新版本后安装&#xff0c;把 C:\Users\用户名\AppData\Local\Doubao\Application 文件夹的文件&#xff0c;拷贝替换 DoubaoPortable\App\Doubao 文件夹的文件&#xff0c;就升级成功了。 再把安装的豆包彻底卸载就可以。 桌面版比网页版…

【MySQL】索引失效问题详解

目录 1. 最左前缀原则 2. 条件左边有函数或运算 3. 隐式类型转换 4. LIKE 模糊查询以 % 开头 5、MySQL 优化器选择全表扫描 ⭐对 in 关键字特别说明⭐ &#xff08;1&#xff09;列表太大时&#xff0c;走全表扫描了 &#xff08;2&#xff09;隐式类型转换 &#xff…

优选算法第十讲:字符串

优选算法第十讲&#xff1a;字符串 1.最长公共前缀2.最长回文子串3.二进制求和4.字符串相乘 1.最长公共前缀 2.最长回文子串 3.二进制求和 4.字符串相乘

【扣子Coze 智能体案例四】五行八卦占卜智能体

目录 一、意图识别 二、时间格式转换 三、八字转换 四、八字提取 五、八字提取2 六、数据汇总 七、统计五行占比 八、雷达图生成 九、表格生成 十、AI占卜 十一、结束节点 一、意图识别 用户输入的信息包含各种时间格式的年月日时 用户输入的信息包含天干地支八字…

5.学习笔记-SpringMVC(P61-P70)

SpringMVC-SSM整合-接口测试 (1)业务层接口使用junit接口做测试 (2)表现层用postman做接口测试 (3)事务处理— 1&#xff09;在SpringConfig.java&#xff0c;开启注解&#xff0c;是事务驱动 2&#xff09;配置事务管理器&#xff08;因为事务管理器是要配置数据源对象&…

【专题刷题】二分查找(一):深度解刨二分思想和二分模板

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…