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

相关推荐
恋猫de小郭31 分钟前
Flutter 设计包解耦新进展,material_ui 和 cupertino_ui 发布预告
android·前端·flutter
子辰ToT1 小时前
LearnOpenGL——高级光照(七)HDR
笔记·图形渲染·opengl
山岚的运维笔记2 小时前
SQL Server笔记 -- 第63章:事务隔离级别
数据库·笔记·sql·microsoft·oracle·sqlserver
lili-felicity3 小时前
进阶实战 Flutter for OpenHarmony:InteractiveViewer 组件实战 - 图片手势缩放查看系统
flutter
lili-felicity3 小时前
进阶实战 Flutter for OpenHarmony:path_provider 第三方库实战 - 文件存储管理系统
flutter
智者知已应修善业3 小时前
【排列顺序判断是否一次交换能得到升序】2025-1-28
c语言·c++·经验分享·笔记·算法
HuDie3403 小时前
AI产品经理课程笔记
人工智能·笔记·产品经理
lili-felicity3 小时前
进阶实战 Flutter for OpenHarmony:flutter_contacts 第三方库实战 - 智能通讯录管理系统
flutter
lingliang4 小时前
Web3学习笔记:Day2-Solidity基础语法
笔记·学习·web3