Flutter使用FutureBuilder出现结果异常、UI卡顿及进度条显示异常问题
问题原因
- Dart 所有默认代码都运行在主Isolate(即UI线程)中,你用到的argon2密码哈希属于CPU密集型计算任务,即便你用了
await、方法返回了Future,只要计算逻辑在主Isolate执行,就会阻塞UI线程的帧渲染逻辑,导致LinearProgressIndicator的动画无法正常绘制,等到计算完成后UI才会一次性更新,所以会出现进度条仅闪一下、几乎看不到动画的问题。 - 附加问题:你当前直接在
FutureBuilder的future参数中调用_process()方法,会导致Result组件每次重绘时都会重新触发一次计算任务,属于不必要的性能损耗。
解决方案
- 将CPU密集型计算转移到独立Isolate执行,避免阻塞主UI线程
Dart提供了compute方法可以快速创建独立Isolate执行耗时任务,注意传入compute的执行函数必须是顶层函数或者类的静态方法:
- 将CPU密集型计算转移到独立Isolate执行,避免阻塞主UI线程
// 顶层哈希计算函数 Future<String> calculateHash(String inputText) async { return await argon2.hashPasswordString(inputText, salt: Salt.newSalt()); } // 修改原来的_process方法 Future<String> _process() async { return await compute(calculateHash, 'dummy text'); }
- 提前初始化Future避免重复执行计算
在Result组件的initState生命周期中提前初始化计算任务的Future,绑定到FutureBuilder时直接传入变量即可:
- 提前初始化Future避免重复执行计算
class ResultState extends State<Result> { late Future<String> _resultFuture; @override void initState() { super.initState(); _resultFuture = _process(); } @override Widget build(BuildContext context) { return FutureBuilder<String>( future: _resultFuture, // 原有builder逻辑保持不变 builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center( child: LinearProgressIndicator(), ); } else { if (snapshot.error != null) { return const Center( child: Text('An error occurred'), ); } else { return Text('${snapshot.data}'); } } }, ); } Future<String> _process() async { return await compute(calculateHash, 'dummy text'); } }
内容的提问来源于stack exchange,提问作者rozerro
相关产品推荐
相关产品推荐

