我在同步提供程序创建时遇到问题。 我是新手,我会尽力解释得更好。
在我的main.dart中,我有两个提供程序,一个用于用户auth,另一个用于代码中的另一个小部件,它仅具有要显示的列表。 我使用ChangeNotifierProxyProvider,因为所有其他提供程序都需要访问用户身份验证令牌和详细信息。用户存储,读取令牌的所有方法都在userProvider中。
调用UserProvder.init()时,虽然创建了对象,但由于http请求仍未准备好,所以主体中的代码继续执行,并将UserProvider传递给认为UserProvider已准备好但已经准备好的Conto Provider。不。当ContoProvider开始使用UserProvider中的令牌通过UserService访问检索列表时,调用仍然失败,因为它仍然为空。
那么,我该如何同步提供者的创建,以等待UserProvider准备就绪,然后初始化所有其他提供者?
main.dart
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider.init(),
),
ChangeNotifierProxyProvider<UserProvider, ContoProvider>(
create: (_) {
return ContoProvider.init(
Provider.of<UserProvider>(_, listen: false));
},
update: (_, userProvider, contoProvider) =>
contoProvider..update(userProvider),
),
],
child:...
userProvider.dart
User activeUser = User(null, null, null);
UserStatus status = UserStatus.Checking;
UserProvider.init() {
checkUserPresence();
}
void checkUserPresence() async {
/*here i check if in secure storage there is a refreshtoken if there is i make an http
request for a new token and a second request to fill the User into UserProvider so i need await async*/
}
ContoProvider.dart
UserProvider userService;
ContoProvider.init(UserProvider user) {
userService = user;
lookUpConti();
}
void lookUpConti() async {
/*here i make an http call to retrive some data, i access to
userService for get token and refresh token if needed*/
}
答案 0 :(得分:1)
您可以使用WidgetsFlutterBinding.ensureInitialized()
void main() {
/** WidgetsFlutterBinding.ensureInitialized() is required in Flutter v1.9.4+ before using any plugins if the code is executed before runApp. */
WidgetsFlutterBinding.ensureInitialized();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<UserProvider>(
create: (_) => UserProvider.init()),
ChangeNotifierProxyProvider<UserProvider, ContoProvider>(
create: (_) {
return ContoProvider.init(
Provider.of<UserProvider>(_, listen: false));
},
update: (_, userProvider, contoProvider) =>
contoProvider..update(userProvider),
),
],
child: MyApp(),
),
}
PS :我建议您将存储库与提供商分开。也就是说,不应在提供程序中找到对外部/ Web资源的API调用。您可以将此类作为参数传递给您的提供程序。