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

Flutter基础(Isolate)

🧱 1. ​​Isolate 是什么?—— “独立的小房间”​

  • ​每个 Isolate 都是独立运行的​​:就像公司里每个员工有自己的办公室,互不干扰。一个房间卡住了(比如计算太复杂),其他房间照样工作。
  • ​不共享内存​​:员工之间不能直接翻对方的文件柜(内存隔离),只能通过“传纸条”(消息传递)沟通。
  • ​解决卡顿问题​​:Flutter 的 UI 在主 Isolate(主线程)运行,如果主房间在干重活(如解析大文件),UI 就会卡住。这时把重活扔给另一个 Isolate,UI 就流畅了。

⚙️ 2. ​​为什么需要 Isolate?—— “不让主线程累趴”​

  • ​主线程负责 UI​​:所有按钮点击、动画渲染都在主线程跑。
  • ​耗时任务会阻塞 UI​​:比如计算 1 亿次加法、读取超大文件、处理图像。这些任务如果在主线程跑,App 就卡成幻灯片。
  • ​Isolate 的用途​​:把这些耗时任务丢到另一个 Isolate 后台执行,主线程继续流畅响应用户操作。

🛠️ 3. ​​怎么用 Isolate?—— “两种开小号方式”​

(1) ​​手动创建:Isolate.spawn()

适合复杂任务,需要自己管理消息传递:

import 'dart:isolate';// 后台任务函数(必须是静态函数或全局函数)
void backgroundTask(SendPort sendPort) {int result = 0;for (int i = 0; i < 1000000000; i++) {result += i; // 模拟耗时计算}sendPort.send(result); // 把结果传回主线程
}void main() async {ReceivePort receivePort = ReceivePort(); // 主线程的“收件箱”await Isolate.spawn(backgroundTask, receivePort.sendPort); // 启动新 Isolate// 监听结果receivePort.listen((result) {print("计算结果:$result");receivePort.close(); // 关闭收件箱});
}

处理两个任务的代码

import 'dart:async';
import 'dart:isolate';
import 'package:flutter/material.dart';// 任务1:模拟图像处理(高斯模糊)
Future<String> _processImage(String imagePath) async {await Future.delayed(const Duration(seconds: 2)); // 模拟耗时return "处理成功: ${imagePath.split('/').last} (模糊度: 10px)";
}// 任务2:模拟网络请求(获取用户数据)
Future<String> _fetchUserData(int userId) async {await Future.delayed(const Duration(seconds: 3)); // 模拟网络延迟if (userId > 100) throw Exception("用户ID无效");return "用户数据: {id: $userId, name: '用户$userId'}";
}// 启动两个 Isolate 并汇总结果
Future<Map<String, dynamic>> runParallelTasks() async {final ReceivePort resultPort = ReceivePort();final Completer<Map<String, dynamic>> completer = Completer();// 错误收集器final errors = {};// 任务计数器int completedCount = 0;const totalTasks = 2;resultPort.listen((message) {if (message is Map) {final String taskType = message['type'];if (message.containsKey('result')) {completer.isCompleted? null: completer.complete({...completer.future.then((v) => v) ?? {}, taskType: message['result']});} else if (message.containsKey('error')) {errors[taskType] = message['error'];}completedCount++;}// 所有任务完成(成功或失败)if (completedCount == totalTasks) {resultPort.close();if (errors.isNotEmpty) completer.completeError(errors);}});// 启动图像处理 IsolateIsolate.spawn(_isolateTaskHandler,{'type': 'image','task': () => _processImage('assets/images/photo.jpg'),'sendPort': resultPort.sendPort,},);// 启动网络请求 IsolateIsolate.spawn(_isolateTaskHandler,{'type': 'network','task': () => _fetchUserData(200), // 此处故意传入错误ID触发异常'sendPort': resultPort.sendPort,},);return completer.future;
}// Isolate 任务处理器
void _isolateTaskHandler(Map<String, dynamic> message) async {final String type = message['type'];final Function task = message['task'];final SendPort sendPort = message['sendPort'];try {final result = await task();sendPort.send({'type': type, 'result': result});} catch (e) {sendPort.send({'type': type, 'error': e.toString()});}
}// 界面组件
class ParallelIsolateDemo extends StatefulWidget {const ParallelIsolateDemo({super.key});@overrideState<ParallelIsolateDemo> createState() => _ParallelIsolateDemoState();
}class _ParallelIsolateDemoState extends State<ParallelIsolateDemo> {Map<String, dynamic>? _results;String? _error;void _startTasks() async {setState(() {_results = null;_error = null;});try {final results = await runParallelTasks();setState(() => _results = results);} catch (e) {setState(() => _error = "错误: ${e.toString()}");}}@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('双任务并行 Isolate')),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [ElevatedButton(onPressed: _startTasks,child: const Text('启动双任务'),),const SizedBox(height: 20),if (_results != null) ...[Text('图像结果: ${_results!['image']}'),Text('网络结果: ${_results!['network']}'),],if (_error != null)Text(_error!, style: const TextStyle(color: Colors.red)),],),),);}
}// 应用入口
void main() => runApp(MaterialApp(home: Scaffold(body: Center(child: ParallelIsolateDemo())),),);

http://www.lqws.cn/news/558829.html

相关文章:

  • cocos creator 3.8 - 精品源码 - 六边形消消乐(六边形叠叠乐、六边形堆叠战士)
  • docker解析
  • Netty 揭秘CompositeByteBuf:零拷贝优化核心技术
  • Flutter基础(路由页面跳转)
  • Neo4j无法建立到 localhost:7474 服务器的连接出现404错误
  • Nacos源码之服务拉取(RestTemplate)
  • 访问不了/druid/index.html (sql.html 或 login.html)
  • CPU内部总线方式对比
  • 领域驱动设计(DDD)【20】之值对象(Value Object):入门
  • Spring Cloud 微服务(负载均衡策略深度解析)
  • nt!IoSynchronousPageWrite函数分析之atapi!IdeReadWrite----非常重要
  • 23种设计模式——策略模式:像换口红一样切换你的算法
  • Learning to Prompt for Continual Learning
  • 数据结构与算法 --- 双向链表
  • 问卷标记语言(QML):简化调查问卷设计与部署的XML解决方案
  • 【YOLOv13保姆级教程#03】自建数据集训练与验证(Train Val)全流程 | 手把手教你构建数据集、标签格式转换与yaml配置
  • Go开发工程师-Golang基础知识篇
  • Vue工程化实现约定式路由自动注册
  • 使用vue3构建一套网站
  • TCP 和 UDP 是什么?
  • 【Python基础】06 实战:视频压缩迷你脚本设计
  • 深入理解C#委托操作:添加、移除与调用全解析
  • 港澳地区,海外服务器ping通可能是地区运营商问题
  • MySQL为什么要使用b+树
  • 1 Studying《Computer Architecture A Quantitative Approach》1-4
  • 鸿蒙HarmonyOS 5小游戏实践:数字记忆挑战(附:源代码)
  • 信号处理学习——文献精读与code复现之TFN——嵌入时频变换的可解释神经网络(下)
  • 给定一个整型矩阵map,求最大的矩形区域为1的数量
  • Insar 相位展开真实的数据集的生成与下载(随机矩阵放大,zernike 仿真包裹相位)
  • Launcher3中的CellLayout 和ShortcutAndWidgetContainer 的联系和各自职责