当前位置: 首页 > web >正文

Flutter 线程模型详解:主线程、异步与 Isolate


一、主线程:默认的执行环境

所有代码默认运行在主线程。下面的例子展示了一个会阻塞主线程的错误示范:

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});Widget build(BuildContext context) {return MaterialApp(home: HomePage(),);}
}class HomePage extends StatefulWidget {State<HomePage> createState() => _HomePageState();
}class _HomePageState extends State<HomePage> {String _result = '点击按钮开始计算';bool _isLoading = false;// 一个模拟的、非常耗时的同步计算函数// 这会严重阻塞主线程!int _expensiveTask(int number) {int sum = 0;for (int i = 0; i < number; i++) {sum += i;}return sum;}void _doTaskOnMainThread() {setState(() {_isLoading = true;});// 这个计算直接在UI线程上运行,会导致界面卡死int result = _expensiveTask(10000000000); // 一个很大的数setState(() {_result = '计算结果: $result';_isLoading = false;});}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('线程模型实战')),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [if (_isLoading) const CircularProgressIndicator(),Text(_result, style: Theme.of(context).textTheme.headlineSmall),ElevatedButton(onPressed: _doTaskOnMainThread,// 点击这个按钮后,UI会完全卡住,连Loading圈都无法转动child: const Text('在主线程执行耗时任务 (错误示范)'),),],),),);}
}

现象:点击按钮后,即使看到了 Loading 圆圈,它也会完全冻结,无法动画,直到计算完成。这就是阻塞主线程的后果。


二、异步操作:处理 I/O 任务(网络请求为例)

使用 async/await 和 Future 处理不会阻塞线程的“等待型”任务。

// ... 承接上面的 State class ...// 在 _HomePageState 类中添加新方法
Future<void> _fetchDataAsync() async {setState(() {_isLoading = true;_result = '正在加载...';});// 使用 async/await 进行异步网络请求// http.get 是非阻塞的,它向系统发出请求后就直接返回了try {// 记得添加 http 包: flutter pub add http// import 'package:http/http.dart' as http;final response = await http.get(Uri.parse('https://api.example.com/data'));// 这里的代码会在网络请求成功后,由事件循环调度执行// 它仍然运行在主线程,但等待期间主线程是空闲的,可以处理其他事件(如动画)if (response.statusCode == 200) {setState(() {_result = '获取成功: ${response.body.substring(0, 100)}...';});} else {setState(() {_result = '请求失败: ${response.statusCode}';});}} catch (e) {setState(() {_result = '发生错误: $e';});} finally {setState(() {_isLoading = false;});}
}// 在 build 方法的 Column 中添加新的按钮
ElevatedButton(onPressed: _fetchDataAsync,child: const Text('执行异步网络请求 (正确示范)'),
),

现象:点击按钮后,Loading 圆圈流畅旋转,UI 可以正常响应。数据获取完成后,结果会更新到屏幕上。


三、Isolate:处理 CPU 密集型任务

使用 compute 函数将耗时计算任务移到后台 Isolate。

// 1. 首先,在文件顶部导入 foundation.dart
import 'package:flutter/foundation.dart';// 2. 确保耗时函数是顶级函数或静态方法
// 因为 Isolate 不能访问原实例中的非静态成员
int _expensiveTaskInIsolate(int number) {int sum = 0;for (int i = 0; i < number; i++) {sum += i;}return sum;
}// 3. 在 _HomePageState 类中添加新方法
void _doTaskInIsolate() async {setState(() {_isLoading = true;_result = '在Isolate中计算...';});// 使用 compute 将函数和参数抛到新的Isolate中执行// 这是一个非阻塞调用,会立即返回一个Futureint result = await compute(_expensiveTaskInIsolate, 10000000000);// compute 完成后,这里的代码会在主线程执行,可以安全地更新UIsetState(() {_result = 'Isolate计算结果: $result';_isLoading = false;});
}// 4. 在 build 方法的 Column 中添加新的按钮
ElevatedButton(onPressed: _doTaskInIsolate,child: const Text('使用Isolate执行计算 (正确示范)'),
),

现象:点击按钮后,Loading 圆圈流畅旋转,UI 操作完全正常,毫无卡顿。计算完成后,结果会更新到屏幕上。


最终效果对比

你的 build 方法中的 Column 最终会有三个按钮:

Column(mainAxisAlignment: MainAxisAlignment.center,children: [if (_isLoading) const CircularProgressIndicator(),Text(_result, style: Theme.of(context).textTheme.headlineSmall),ElevatedButton(onPressed: _doTaskOnMainThread,child: const Text('在主线程执行耗时任务 (错误示范)'),),SizedBox(height: 10),ElevatedButton(onPressed: _fetchDataAsync,child: const Text('执行异步网络请求 (正确示范)'),),SizedBox(height: 10),ElevatedButton(onPressed: _doTaskInIsolate,child: const Text('使用Isolate执行计算 (正确示范)'),),],
)

总结一下:

· 错误示范按钮:会让你体验到应用卡死的糟糕感觉。
· 异步网络请求按钮:展示了如何用 async/await 正确处理 I/O 操作。
· Isolate 计算按钮:展示了如何用 compute 正确处理 CPU 密集型任务。

通过这个实战对比,你能清晰地看到三种方式的巨大差异,并理解在正确场景使用正确工具的重要性。

http://www.xdnf.cn/news/18502.html

相关文章:

  • 机器学习中的两大核心算法:k 均值聚类与集成学习
  • Linux之Ansible自动化运维(二)
  • 分布式集群压测+grafana+influxdb+Prometheus详细步骤
  • 小程序个人信息安全检测技术:从监管视角看加密与传输合规
  • 【StarRocks】-- SQL CTE 语法
  • Ubuntu22.04安装VMware Tools
  • STM32H750 CoreMark跑分测试
  • Chrome/360 浏览器 WebUI 资源底层机制解析:共享资源与专属资源的奥秘
  • Web自动化测试:测试用例流程设计
  • 如何处理项目中棘手的依赖版本冲突问题
  • Eino 框架组件协作指南 - 以“智能图书馆建设手册”方式理解
  • PHP:历经岁月仍熠熠生辉的服务器端脚本语言
  • 三大图计算框架深度对比
  • 桥梁设计模式
  • IPSec 安全基础
  • 域名污染怎么清洗?域名污染如何处理?
  • 无人机长距离高速传输技术解析
  • DAY44打卡
  • 2026济南国际展会全攻略:玉米及淀粉深加工技术革新新动态
  • 【C++】继承(详解)
  • 2025-08-21 Python进阶6——迭代器生成器与with
  • 阿里云搭建flask服务器
  • 【C++】类和对象——默认成员函数(中)(附思维导图)
  • .NET Core MongoDB 查询数据异常及解决
  • 2 Nacos 集群的数据同步机制
  • 服务发现与负载均衡:Kubernetes Service核心机制深度解析
  • 在Excel和WPS表格中合并多个单元格这样最快
  • Web15- Java Web安全:防止XSS与CSRF攻击
  • 银河麒麟V10系统离线安装zabbix-agent教程
  • 机器学习3