Flutter:如何将同步静态方法与异步非静态方法同步?

时间:2021-06-02 08:17:50

标签: flutter dart

当我启动应用程序时,它应该检查是否可以使用生物识别身份验证(指纹/面部识别码)。我有一个类来检查这个,登录页面需要它的结果。我有以下代码:

class LocalAuthenticationUtil with ChangeNotifier {
  static LocalAuthentication _auth = LocalAuthentication();
  static List<BiometricType> biometricTypes;
  static bool haveBiometrics = true;
  bool _biometricAuthenticated = true;

  static LocalAuthenticationUtil _instance;

  static LocalAuthenticationUtil getInstance() {
    if (_instance == null) {
      _instance = LocalAuthenticationUtil();
      print("GetInstance CanCheckBiometrics before");
      _instance._canCheckBiometrics();
      print("GetInstance CanCheckBiometrics after");
      if (haveBiometrics) {
        _instance.addListener(() {
          _instance.authenticate();
        });
        _instance.authenticate();
      }
    }

    return _instance;
  }

  Future<void> _canCheckBiometrics() async {
    print("CanCheckBiometrics before");
    haveBiometrics = await _auth.canCheckBiometrics;
    print("CanCheckBiometrics after");
    if (haveBiometrics) {
      biometricTypes = await _auth.getAvailableBiometrics();
    }
  }

  set biometricAuthenticated(bool value) {
    if (_biometricAuthenticated != value) {
      _biometricAuthenticated = value;
      notifyListeners();
    }
  }

代码运行结果如下:

I/flutter (23495): GetInstance CanCheckBiometrics before
I/flutter (23495): CanCheckBiometrics before
I/flutter (23495): GetInstance CanCheckBiometrics after
I/flutter (23495): CanCheckBiometrics after

虽然我想要发生的顺序是:

I/flutter (23495): GetInstance CanCheckBiometrics before
I/flutter (23495): CanCheckBiometrics before
I/flutter (23495): CanCheckBiometrics after
I/flutter (23495): GetInstance CanCheckBiometrics after

2 个答案:

答案 0 :(得分:1)

你没有await_instance._canCheckBiometrics();

Dart 同步执行,直到遇到 await,此时函数会立即返回,但“记住它在哪里”,因此当 await 被 {{ 1}} 完成:

这里,当您调用 Future 时,它立即运行第一个 _instance._canCheckBiometrics() 语句,然后命中 print 并立即返回一个 await _auth.canCheckBiometrics,表示 {{1} 的结果}}。

只需将 Future 替换为 _instance._canCheckBiometrics() 就可以了。

顺便说一句,您可以创建一个 _instance._canCheckBiometrics() 文件来自定义您的项目的 linter 警告。特别是当您在没有 await _instance._canCheckBiometrics() 的异步上下文中有 analysis_options.yaml 返回函数时,名为 unawaited_futures 的函数会警告您。这通常是一个错误,但如果您确定,您可以手动取消它。此规则通常有助于捕获此类错误。 要使用 linter,请查看:https://dart.dev/guides/language/analysis-options#enabling-linter-rules

答案 1 :(得分:0)

cameron1024 是对的。 您需要做的是创建一个 StatefulWidget,它会在检查完成后重定向用户。

class AuthWidget extends StatefulWidget {
  AuthWidget({Key key}) : super(key: key);

  @override
  _AuthWidgetState createState() => _AuthWidgetState();
}

class _AuthWidgetState extends State<AuthWidget> {
  @override
  void initState() { 
    super.initState();
    checkBiometrics(); // perform the check asynchronously and then use Navigator.of(context).push/replace
  }
  @override
  Widget build(BuildContext context) {
    // Display a loader while checking
    return CircularProgressIndicator();
  }
}
相关问题