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

Flutter Isolate解决耗时任务导致卡死

先来对比一下在Flutter的ui主线程下直接计算一个耗时任务的情况:

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: H(),
  ));
}

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

  @override
  State<H> createState() => _HState();
}

class _HState extends State<H> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("耗时计算"),
      ),
      body: Center(
        child: Text("$_count"),
      ),
      floatingActionButton: FloatingActionButton(
          child: const Text("start"),
          onPressed: () {
            _count = countPrimes(100000000);
            setState(() {});
          }),
    );
  }
}

// 计算质数个数
int countPrimes(int n) {
  List<bool> isPrime = List.filled(n + 1, true);
  isPrime[0] = isPrime[1] = false;

  for (int i = 2; i * i <= n; i++) {
    if (isPrime[i]) {
      for (int j = i * i; j <= n; j += i) {
        isPrime[j] = false;
      }
    }
  }
  return isPrime.where((prime) => prime).length;
}

发现点击按钮后,直接卡死,现在换成异步执行:

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: H(),
  ));
}

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

  @override
  State<H> createState() => _HState();
}

class _HState extends State<H> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("耗时计算"),
      ),
      body: Center(
        child: Text("$_count"),
      ),
      floatingActionButton: FloatingActionButton(
          child: const Text("start"),
          onPressed: () async {
            _count = await countPrimes(100000000);
            setState(() {});
          }),
    );
  }
}

// 计算质数个数
Future<int> countPrimes(int n) async {
  List<bool> isPrime = List.filled(n + 1, true);
  isPrime[0] = isPrime[1] = false;

  for (int i = 2; i * i <= n; i++) {
    if (isPrime[i]) {
      for (int j = i * i; j <= n; j += i) {
        isPrime[j] = false;
      }
    }
  }
  return isPrime.where((prime) => prime).length;
}

发现仍旧会卡死,因为计算过程还是发生在ui线程中,现在使用isolate进行对比:

import 'dart:isolate';

import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(
    home: H(),
  ));
}

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

  @override
  State<H> createState() => _HState();
}

class _HState extends State<H> {
  int _count = 0;
  ReceivePort? _receivePort;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("耗时计算"),
      ),
      body: Center(
        child: Text("$_count"),
      ),
      floatingActionButton: FloatingActionButton(
          child: const Text("start"),
          onPressed: () {
            _receivePort = ReceivePort();

            Isolate.spawn(countPrimes, [100000000, _receivePort!.sendPort]);
            _receivePort!.listen((message) {
              setState(() {
                _count = message;
              });
            });
          }),
    );
  }
}

// 计算质数个数
void countPrimes(List<dynamic> args) {
  int n = args[0];
  SendPort sendPort = args[1];
  List<bool> isPrime = List.filled(n + 1, true);
  isPrime[0] = isPrime[1] = false;

  for (int i = 2; i * i <= n; i++) {
    if (isPrime[i]) {
      for (int j = i * i; j <= n; j += i) {
        isPrime[j] = false;
      }
    }
  }
  sendPort.send(isPrime.where((prime) => prime).length);
}

发现问题得到解决


http://www.kler.cn/a/537072.html

相关文章:

  • 时序数据库:Influxdb详解
  • 力扣.270. 最接近的二叉搜索树值(中序遍历思想)
  • 【Linux网络编程】之守护进程
  • 自动化测试工具selenium的安装踩坑
  • 某团面试题①—kudu读写流程
  • [Deepseek-自定义Ollama 安装路径+lmStudio 简易安装]
  • 工业以太网profinet网关:解锁生产效率提升的“超级钥匙”
  • 【DeepSeek-R1训练笔记】随手记录一些训练log
  • 【leetcode100】岛屿的最大面积
  • Rust语言进阶之标准输入: stdin用法实例(一百零五)
  • CRM系统中的数据分析和报表功能如何帮助企业?
  • 58页PPT学习华为面向业务价值的数据治理实践
  • windows版的docker如何使用宿主机的GPU
  • nas-群晖docker查询注册表失败解决办法(平替:使用SSH命令拉取ddns-go)
  • opentelemetry-collector 配置elasticsearch
  • 设计高效的测试用例:从需求到验证
  • 协议桥梁~Profinet与Ethernet IP的智慧连接完美应用在汽车制造业
  • 【DeepSeek:国产大模型的崛起与ChatGPT的全面对比】
  • leetcode_47全排列II
  • 【Pytorch】nn.RNN、nn.LSTM 和 nn.GRU的输入和输出形状
  • 荣耀内置的远程控制怎样用?荣耀如何远程控制其他品牌的手机?
  • 【GitHub】GitHub 2FA 双因素认证 ( 使用 Microsoft Authenticator 应用进行二次验证 )
  • 121,【5】 buuctf web [RoarCTF 2019] Easy Calc
  • 树莓集团双流布局,元宇宙产业园点亮科技之光
  • 如何确保爬虫不会违反平台规则?
  • 为什么关系模型不叫表模型