Flutter执行bcrypt密码校验时UI卡顿,如何实现校验期间展示加载动画
问题根因
bcrypt密码校验属于CPU密集型运算,默认在Flutter主Isolate执行时会占用UI渲染线程,即使添加await关键字也无法避免UI卡顿。同时现有代码没有加载状态控制逻辑,无法在校验过程中展示加载器。
解决思路
- 新增加载状态标记,校验过程中展示加载动画,同时阻止用户重复提交请求
- 将bcrypt校验逻辑移到独立Isolate中执行,避免阻塞主UI线程,保证加载动画可以正常运行
- 修正异步方法的
await调用逻辑,保证状态更新时机正确
完整修改代码
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; // bcrypt校验逻辑必须为顶级/静态函数,才能通过compute传入独立Isolate执行 Future<bool> verifyBcryptPassword(Map<String, dynamic> params) async { final inputPassword = params['inputPassword'] as String; final storedHash = params['storedHash'] as String; // 替换为你项目中实际使用的bcrypt校验方法 return Bcrypt.checkpw(inputPassword, storedHash); } class _MyWidgetState<MyWidget> extends State<MyWidget> { // 密码校验加载状态标记 bool _isVerifying = false; @override Widget build(BuildContext context) { return Stack( children: [ GetPassCode( PassCodeType.ENTER, // 加载状态下禁用回调,避免重复提交 onDone: _isVerifying ? null : ({context, data}) async { setState(() { _isVerifying = true; }); await unlock( state, data?['password'] ?? '', Languages.of(context) ); setState(() { _isVerifying = false; }); }, goBack: () {}, data: {}, ), // 加载状态展示半透明遮罩 if (_isVerifying) const Opacity( opacity: 0.7, child: ModalBarrier(dismissible: false, color: Colors.black), ), // 加载状态展示居中加载动画 if (_isVerifying) const Center( child: CircularProgressIndicator(), ), ], ); } Future<void> unlock(userState, String? password, Languages strings) async { final user = userState.currentUser; // 将校验逻辑放到独立Isolate执行 final verifyPassed = await compute(verifyBcryptPassword, { 'inputPassword': password ?? '', // 替换为你项目中用户实体类存储密码哈希的对应字段 'storedHash': user.passwordHash, }); if (!verifyPassed) { return; } // 增加mounted判断避免组件销毁后调用上下文异常 if(mounted) { context.read<LockCubit>().unlock(); } } }
注意事项
- 你需要自行替换代码中
Bcrypt.checkpw校验方法、user.passwordHash字段为你项目中的实际对应实现 - 独立Isolate的内存空间和主Isolate隔离,不能直接传递实例对象,所以这里只传递密码和哈希字符串两个基础类型参数
内容的提问来源于stack exchange,提问作者Sajad Rezvani
相关产品推荐
相关产品推荐

