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更新

相关推荐
守护安静星空3 小时前
esp32开发笔记-工程搭建
笔记·单片机·嵌入式硬件·物联网·visual studio code
ljt27249606613 小时前
Compose笔记(七十七)--视频录制
笔记·android jetpack
autumn20053 小时前
Flutter 框架跨平台鸿蒙开发 - 虚拟纪念馆
flutter·华为·harmonyos
不爱吃糖的程序媛3 小时前
拷贝或克隆其他 Flutter OH 项目到本地后无法运行
flutter
2301_822703204 小时前
渐变壁纸生成:基于鸿蒙Flutter的跨平台壁纸创建工具
flutter·华为·harmonyos·鸿蒙
牛马1115 小时前
Flutter BackdropFilter filter
flutter
周周不一样5 小时前
Andorid基础笔记2-jar&反射
笔记·pycharm·jar
智者知已应修善业6 小时前
【51单片机单按键切换广告屏】2023-5-17
c++·经验分享·笔记·算法·51单片机
凉、介7 小时前
别再把 PCIe 的 inbound/outbound、iATU 和 eDMA 混为一谈
linux·笔记·学习·嵌入式·pcie
Utopia^7 小时前
Flutter 框架跨平台鸿蒙开发 - 旅行预算管家
flutter·华为·harmonyos