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

相关推荐
OBiO20132 小时前
Cell | 突破AAV载体容量限制!路中华/姜玉武/刘太安团队开发AAVLINK系统实现大基因递送
笔记
liulian09162 小时前
Flutter for OpenHarmony 跨平台开发:BMI计算器功能实战指南
flutter·华为
智者知已应修善业3 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
sakiko_3 小时前
UIKit学习笔记5-使用UITableView制作聊天页面
笔记·学习·swift·uikit
Alice-YUE4 小时前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript
小陈phd5 小时前
TensorRT 入门完全指南(一)——从核心定义到生态工具全解析
人工智能·笔记
是上好佳佳佳呀5 小时前
【前端(十一)】JavaScript 语法基础笔记(多语言对比)
前端·javascript·笔记
xmdy58665 小时前
Flutter+开源鸿蒙实战|智安盾电商溯源平台Day1 项目搭建与整体方案拆解
flutter·开源·harmonyos
handler015 小时前
Linux 内核剖析:进程优先级、上下文切换与 O(1) 调度算法
linux·运维·c语言·开发语言·c++·笔记·算法
其实防守也摸鱼6 小时前
CTF密码学综合教学指南--第四章
网络·笔记·安全·网络安全·密码学·ctf