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);
}

发现问题得到解决

相关推荐
Lanren的编程日记12 小时前
Flutter鸿蒙应用开发:基础UI组件库设计与实现实战
flutter·ui·harmonyos
西西学代码12 小时前
Flutter---波形动画
flutter
于慨16 小时前
flutter基础组件用法
开发语言·javascript·flutter
恋猫de小郭18 小时前
Android CLI ,谷歌为 Android 开发者专研的 AI Agent,提速三倍
android·前端·flutter
火柴就是我19 小时前
flutter pushAndRemoveUntil 的一次小疑惑
flutter
于慨19 小时前
flutter doctor问题解决
flutter
唔6619 小时前
flutter 图片加载类 图片的安全使用
安全·flutter
Nathan2024061620 小时前
Flutter - InheritedWidget
flutter·dart
恋猫de小郭21 小时前
JetBrains Amper 0.10 ,期待它未来替代 Gradle
android·前端·flutter
Lanren的编程日记1 天前
Flutter鸿蒙应用开发:实时聊天功能集成实战
flutter·华为·harmonyos