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

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

Dart 复制代码
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;
}

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

Dart 复制代码
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进行对比:

Dart 复制代码
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);
}

发现问题得到解决

相关推荐
大厂在职_XpW7 小时前
Flutter 完整开发实战详解(二、 快速开发实战篇)_0_10_flutter dio
windows·flutter
明似水14 小时前
高效管理Dart和Flutter多包项目:Melos工具全解析
android·前端·flutter
大厂在职_fUk15 小时前
Flutter完整开发实战详解(六、 深入Widget原理)
前端·javascript·flutter
天若子16 小时前
flutter Selector 使用
flutter
早起的年轻人1 天前
Flutter List 的 every 如果回调函数抛出异常 应该如何处理
开发语言·python·flutter
健了个平_241 天前
【Cursor初体验】AI开发 Flutter 应用:一款快速预览SVGA的桌面小工具
前端·flutter·ios
1322 天前
独立开发项目阶段总结-需求只有自己有
android·前端·flutter
造梦师2 天前
windows通过FVM管理多个版本flutter
flutter
leluckys3 天前
flutter 专题四十四 关于MacOs Catalina “无法打开***,因为无法验证开发者...”的解决方案
flutter·macos