【问题标题】:What Does WidgetsFlutterBinding.ensureInitialized() do?WidgetsFlutterBinding.ensureInitialized() 有什么作用?
【发布时间】:2020-12-31 12:40:32
【问题描述】:

我正在尝试通过以下代码行使用 Firebase 包。

我真的很想知道这行代码到底做了什么?

官方文档对我帮助不大。谁能给我解释一下?

【问题讨论】:

    标签: firebase flutter dart


    【解决方案1】:

    你必须以这种方式使用它:

    void main() async {
      WidgetsFlutterBinding.ensureInitialized();
      await Firebase.initializeApp();
      runApp(MyApp());
    }
    

    https://flutter.dev/docs/resources/architectural-overview#architectural-layers

    上图是Flutter的架构层,WidgetFlutterBinding是用来和Flutter引擎交互的。 Firebase.initializeApp() 需要调用原生代码来初始化 Firebase,并且由于插件需要使用平台通道来调用原生代码,这是异步完成的,因此您必须调用 ensureInitialized() 以确保您拥有 @ 的实例987654333@.

    来自docs

    返回 WidgetsBinding 的实例,必要时创建并初始化它。如果创建了一个,它将是一个 WidgetsFlutterBinding。如果之前已经初始化过,那么它至少会实现 WidgetsBinding。

    只有在调用runApp之前需要初始化绑定时才需要调用该方法。


    来自source code

      @override
      Future<FirebaseAppPlatform> initializeApp(
          {String name, FirebaseOptions options}) async {
        if (name == defaultFirebaseAppName) {
          throw noDefaultAppInitialization();
        }
    
        // Ensure that core has been initialized on the first usage of
        // initializeApp
        if (!isCoreInitialized) {
          await _initializeCore();
        }
    
        // If no name is provided, attempt to get the default Firebase app instance.
        // If no instance is available, the user has not set up Firebase correctly for
        // their platform.
        if (name == null) {
          MethodChannelFirebaseApp defaultApp =
              appInstances[defaultFirebaseAppName];
    
          if (defaultApp == null) {
            throw coreNotInitialized();
          }
    
          return appInstances[defaultFirebaseAppName];
        }
    
        assert(options != null,
            "FirebaseOptions cannot be null when creating a secondary Firebase app.");
    
        // Check whether the app has already been initialized
        if (appInstances.containsKey(name)) {
          throw duplicateApp(name);
        }
    
        _initializeFirebaseAppFromMap(await channel.invokeMapMethod(
          'Firebase#initializeApp',
          <String, dynamic>{'appName': name, 'options': options.asMap},
        ));
    
        return appInstances[name];
      }
    

    invokeMapMethod 将使用指定参数调用上述通道上的方法,然后在本机代码中调用initializeApp() 方法, https://github.com/FirebaseExtended/flutterfire/blob/master/packages/firebase_core/firebase_core/android/src/main/java/io/flutter/plugins/firebase/core/FlutterFirebaseCorePlugin.java#L227


    还有多种初始化 Firebase 的方法,您可以在此处查看:

    No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp() in Flutter and Firebase

    在其他方式中,我们不调用WidgetsFlutterBinding.ensureInitialized(),因为runApp() 函数在内部调用它:

    void runApp(Widget app) {
      WidgetsFlutterBinding.ensureInitialized()
        ..scheduleAttachRootWidget(app)
        ..scheduleWarmUpFrame();
    }
    

    https://github.com/flutter/flutter/blob/bbfbf1770c/packages/flutter/lib/src/widgets/binding.dart#L1012

    【讨论】:

      【解决方案2】:

      一个简单的答案是,如果Flutter需要在调用runApp之前调用原生代码

      WidgetsFlutterBinding.ensureInitialized();

      确保您有一个 WidgetsBinding 实例,这是使用平台通道调用本机代码所必需的。

      只有在需要绑定时才需要调用这个方法 在调用 runApp 之前初始化。

      【讨论】:

        【解决方案3】:

        一个简单的答案,你需要使用这一行,如果你的主函数使用 async 关键字,因为你在里面使用了 await 语句。

        Future<void> main() async {
          WidgetsFlutterBinding.ensureInitialized();
          SharedPreferences prefs = await SharedPreferences.getInstance(); // just an example
        }
        

        【讨论】:

          猜你喜欢
          • 2022-12-04
          • 1970-01-01
          • 2023-04-10
          • 2011-07-17
          • 2014-09-13
          • 2011-12-30
          • 1970-01-01
          • 2019-04-26
          • 2016-04-29
          相关资源
          最近更新 更多