EnsureInitialization()是做什么的?

我试图使用以下代码行的 Firebase 软件包。

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

官方文件对我没什么帮助,有人能解释一下吗?

Code snippet

46272 次浏览

你必须这样使用它:

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

enter image description here

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

上图是 Flutter 的架构层,WidgetFlutterBinding是用来与 Flutter 引擎进行交互的。Firebase.initializeApp()需要调用本地代码来初始化 Firebase,因为插件需要使用平台通道来调用本地代码,这是异步完成的,所以你必须调用 ensureInitialized()来确保你有一个 WidgetsBinding的实例。

来自 医生:

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

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


来自 源代码:

  @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


There are also different ways to initialize Firebase, which you can check here:

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

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

WidgetsFlutterBinding.ensureInitialized();

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

只有在需要绑定为 在调用 runApp 之前初始化。

一个简单的答案是,如果您的主函数使用了异步关键字,因为您在其中使用了 wait 语句,那么您需要使用这一行。

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