先来对比一下在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);
}
发现问题得到解决