异步导航到不同的页面
Asynchronously navigate to a different page
我编写了一个需要身份验证的应用程序。我还在设备上安全地保存了永久身份验证数据,因此每次启动应用程序时都不需要手动登录。
应用程序一启动,它就会自动路由到主路由(在我的例子中,这是一个无状态的启动画面)。执行以下代码:
@override
Widget build(BuildContext context) {
ifLoggedIn(context);
return Scaffold(
body: Center(
child: Image.asset("assets/logo-sm.png", width: 200,),
),
);
}
void ifLoggedIn(context) async {
if (User.user != null) { // in case of a hot reload resetting the damn app
Navigator.of(context).push(right(PublicStart()));
} else {
User user = await User.loginFromSafeStorage(context); // login from safe storage
if (user != null)
Navigator.of(context).push(right(PublicStart()));
else // nope, no credentials found, redirect to the start-screen
Navigator.of(context).push(up(SignInScreen()));
}
}
ifLoggedIn(context)
函数是一个异步函数,用于检查登录数据是否已经存储在本地。如果是这种情况,它将对用户进行身份验证。
这个过程如下:
Case: Logindata found -> Login user and navigate to the start-screen
Case: No logindata found -> Navigate to the sign-in-screen.
如您所见,由于此函数是异步的,因此返回下面的 Scaffold
并且不会中断该无状态小部件的构建过程。但是...
显然,在构建此小部件期间调用了 setState。我不知道如何或为什么,但它似乎发生了。我已经尝试解决这个问题,但这不是第一次出现,我有一种不好的感觉,我在开发这个应用程序时采用了不好的做法。
我怀疑它与检查登录用户有关。
我经常遇到的另一个错误(我的意思是,真的很多)如下:
Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line <insert number> pos <insert number>: '!_debugLocked': is not true.
其中数字不时变化。据我了解,这是为了防止路由被多次调用或中断与路由有关的任何事情。由于我随机出现此错误,这一定与异步函数有关。
最后确定我的问题:
我在这里做错了什么以及执行上述操作的规范是什么?
编辑(更多说明):
不能从构建方法触发异步调用,因为它(构建方法)可以出于不同原因被调用很多次,所以您不希望您的代码执行多次,因为这会导致不良结果
解决方案是使用有状态小部件并从那里(最好从 initState()
开始)执行必须 运行 一次的代码(在您的情况下是检查身份验证状态的代码)
也看看这个
我编写了一个需要身份验证的应用程序。我还在设备上安全地保存了永久身份验证数据,因此每次启动应用程序时都不需要手动登录。
应用程序一启动,它就会自动路由到主路由(在我的例子中,这是一个无状态的启动画面)。执行以下代码:
@override
Widget build(BuildContext context) {
ifLoggedIn(context);
return Scaffold(
body: Center(
child: Image.asset("assets/logo-sm.png", width: 200,),
),
);
}
void ifLoggedIn(context) async {
if (User.user != null) { // in case of a hot reload resetting the damn app
Navigator.of(context).push(right(PublicStart()));
} else {
User user = await User.loginFromSafeStorage(context); // login from safe storage
if (user != null)
Navigator.of(context).push(right(PublicStart()));
else // nope, no credentials found, redirect to the start-screen
Navigator.of(context).push(up(SignInScreen()));
}
}
ifLoggedIn(context)
函数是一个异步函数,用于检查登录数据是否已经存储在本地。如果是这种情况,它将对用户进行身份验证。
这个过程如下:
Case: Logindata found -> Login user and navigate to the start-screen
Case: No logindata found -> Navigate to the sign-in-screen.
如您所见,由于此函数是异步的,因此返回下面的 Scaffold
并且不会中断该无状态小部件的构建过程。但是...
显然,在构建此小部件期间调用了 setState。我不知道如何或为什么,但它似乎发生了。我已经尝试解决这个问题,但这不是第一次出现,我有一种不好的感觉,我在开发这个应用程序时采用了不好的做法。
我怀疑它与检查登录用户有关。
我经常遇到的另一个错误(我的意思是,真的很多)如下:
Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line <insert number> pos <insert number>: '!_debugLocked': is not true.
其中数字不时变化。据我了解,这是为了防止路由被多次调用或中断与路由有关的任何事情。由于我随机出现此错误,这一定与异步函数有关。
最后确定我的问题: 我在这里做错了什么以及执行上述操作的规范是什么?
编辑(更多说明):
不能从构建方法触发异步调用,因为它(构建方法)可以出于不同原因被调用很多次,所以您不希望您的代码执行多次,因为这会导致不良结果
解决方案是使用有状态小部件并从那里(最好从 initState()
开始)执行必须 运行 一次的代码(在您的情况下是检查身份验证状态的代码)
也看看这个