Flutter笔记--Isolate

这一节了解一下Flutter中的Isolate,在Flutter开发中,Isolate是Dart语言提供的并发执行机制,用于在不阻塞UI线程的前提下执行耗时任务(如计算、文件处理),由于Dart默认是单线程事件循环模型,所有代码都在同一个Isolate中运行。一旦执行长时间同步操作,就会导致界面卡顿。简单总结:

API:

Isolate.spawn<T>(...):启动一个新的Isolate。

entryPoint:新Isolate的入口函数。

message:传递给入口函数的初始数据。

onExit/onError:监听子Isolate退出或报错。

SendPort:用于向另一个Isolate发送消息。

ReceivePort:用于接收来自其他Isolate的消息。(只能在创建它的Isolate中使用,调用.listen(callback)监听消息流)。

Isolate.exit(sendPort,result):从子Isolate直接返回结果并退出。

Isolate.kill():终止Isolate,释放Isolate资源,避免内存泄漏。

通信逻辑:

栗子:

Dart 复制代码
import 'dart:isolate';
import 'package:flutter/material.dart';

class IsolateDemo extends StatefulWidget {
  const IsolateBasicDemo({super.key});

  @override
  State<IsolateBasicDemo> createState() => _IsolateBasicDemoState();
}

class _IsolateBasicDemoState extends State<IsolateBasicDemo> {
  String _result = '计算结果:--';
  bool _isCalculating = false;
  static void _calculateTask(SendPort sendPort) {

    int sum = 0;
    for (int i = 1; i <= 100000000; i++) {
      sum += i;
    }

    sendPort.send(sum);
  }

  Future<void> _startCalculation() async {
    setState(() {
      _isCalculating = true;
      _result = '计算中...';
    });


    final receivePort = ReceivePort();
    try {
  
      final isolate = await Isolate.spawn(
        _calculateTask,
        receivePort.sendPort, 
      );
   
      receivePort.listen((message) {
        setState(() {
          _result = '计算结果:$message';
          _isCalculating = false;
        });
      
        receivePort.close();
        isolate.kill(priority: Isolate.immediate);
      });
    } catch (e) {
      setState(() {
        _result = '计算失败:$e';
        _isCalculating = false;
      });
      receivePort.close();
    }
  }

  @override
  Widget build(BuildContext context) {
    return
      Scaffold(
      appBar: AppBar(title: const Text('Isolate用法')),
      body: Container(
        height: 300,
        width: 400,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_result, style: const TextStyle(fontSize: 20)),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _isCalculating ? null : _startCalculation,
              child: const Text('开始计算(1亿累加)'),
            ),
          ],
        ),
      ),
    );
  }
}
Dart 复制代码
import 'dart:async';
import 'dart:isolate';
import 'package:flutter/material.dart';

class IsolateDemo extends StatefulWidget {
  const IsolateDemo({super.key});

  @override
  State<IsolateDemo> createState() => _IsolateTwoWayDemoState();
}

class _IsolateTwoWayDemoState extends State<IsolateDemo> {
  String _progress = '进度:0%';
  bool _isRunning = false;
  SendPort? _isolateSendPort; 
  Isolate? _isolate;

  static void _progressTask(SendPort mainSendPort) {

    final receivePort = ReceivePort();
    mainSendPort.send(receivePort.sendPort);
    int progress = 0;

    receivePort.listen((message) {
      if (message == 'start') {

        Timer.periodic(const Duration(milliseconds: 100), (timer) {
          progress += 1;
          mainSendPort.send(progress); 
          if (progress >= 100) {
            timer.cancel();
            receivePort.close();
          }
        });
      }
    });
  }

  Future<void> _startTask() async {
    setState(() {
      _isRunning = true;
      _progress = '进度:0%';
    });

    final mainReceivePort = ReceivePort();
    _isolate = await Isolate.spawn(_progressTask, mainReceivePort.sendPort);

    mainReceivePort.listen((message) {
      if (message is SendPort) {
        _isolateSendPort = message;
        _isolateSendPort?.send('start');
      } else if (message is int) {
        setState(() {
          _progress = '进度:$message%';
        });
        if (message >= 100) {
          setState(() => _isRunning = false);
          mainReceivePort.close();
          _isolate?.kill();
        }
      }
    });
  }

  @override
  void dispose() {
    _isolate?.kill();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Isolate Demo')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_progress, style: const TextStyle(fontSize: 20)),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _isRunning ? null : _startTask,
              child: const Text('开始模拟进度任务'),
            ),
          ],
        ),
      ),
    );
  }
}

注意:

1 入口函数必须是顶级函数或静态方法

2 传递的数据必须可序列化

3 避免频繁创建Isolate

4 子Isolate无法操作UI,结果必须传回主Isolate更新

相关推荐
[H*]2 小时前
鸿蒙跨端Flutter学习:InheritedWidget嵌套使用
学习·flutter
weixin_440730502 小时前
02测试基础知识笔记
笔记
就叫飞六吧2 小时前
Jenkins 流水线全流程实战笔记
笔记·servlet·jenkins
别了,李亚普诺夫2 小时前
运算放大器的参数、选型与应用-学习笔记
笔记·学习
中屹指纹浏览器2 小时前
指纹浏览器网络隔离与泄漏防护技术全解析——从架构设计到落地实践摘要
经验分享·笔记
小白阿龙2 小时前
鸿蒙+flutter 跨平台开发——决策工具的开发实现
flutter·华为·harmonyos·鸿蒙
生擒小朵拉2 小时前
ROS1学习笔记(一)
笔记·学习
丝斯20112 小时前
AI学习笔记整理(52)——大模型之Agent 智能体
人工智能·笔记·学习
lpfasd1233 小时前
《开发者技术及生态发展2030》研读报告
笔记·程序人生