You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:24:03