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