Flutter 等待 Provider 准备好在 multiprovider 中

Posted

技术标签:

【中文标题】Flutter 等待 Provider 准备好在 multiprovider 中【英文标题】:Flutter await Provider to be ready inside multiprovider 【发布时间】:2020-06-21 04:28:43 【问题描述】:

我在创建同步提供程序时遇到问题。 我是 Flutter 的新手,我会尽力解释得更好。

在我的 main.dart 中,我有两个提供程序,一个用于用户身份验证,一个用于代码中的另一个小部件,它只是有一个要显示的列表。 我使用 ChangeNotifierProxyProvider 因为所有其他提供者都需要访问用户身份验证令牌和详细信息。用户存储、读取令牌的所有方法都在 userProvider 中。

当调用 UserProvder.init() 时,对象已创建但由于 http 请求仍未准备好,main 中的代码继续执行并将 UserProvider 传递给认为 UserProvider 已准备好但它已准备好的 Conto Provider不是。当 ContoProvider 开始使用 UserProvider 中的令牌检索 List 时,通过 userService 访问失败,因为仍然为 null。

那么,我怎样才能同步提供者的创建,以便等待 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*/
    

【问题讨论】:

【参考方案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 调用。您可以将此类作为参数传递给您的提供者。

【讨论】:

是的,您对架构的看法是绝对正确的。在这个月里,我学到了很多东西,并且多次改变了我的架构。无论如何感谢您的回复:) 不客气。如果是这样的话,如果您将其标记为正确,我将不胜感激。

以上是关于Flutter 等待 Provider 准备好在 multiprovider 中的主要内容,如果未能解决你的问题,请参考以下文章

flutter中的状态管理Provider

Flutter - Provider 变量更改时触发导航

Flutter Provider源码分析

flutter_bloc/provider RepositoryProvider vs Provider

Flutter - Provider - 如何根据 Provider 的值更改 UI?

Flutter:如何用 Provider 播放动画?