Flutter中你需要知道的WidgetsFlutterBinding

26 阅读3分钟

WidgetsFlutterBinding的作用

WidgetsFlutterBinding.ensureInitialized() 方法的主要作用是确保 Flutter 的 WidgetsBinding被初始化。WidgetsBinding 是 Flutter 框架的核心绑定类之一,它负责将 Flutter 的 widget 层与 Flutter 引擎连接起来,使得 Flutter 应用能够与底层的渲染、输入、生命周期管理等系统进行交互。

具体功能

1. 初始化 Flutter 引擎和绑定系统

在 Flutter 应用启动时,需要初始化一系列的底层系统,如渲染系统、输入系统、手势识别系统等。WidgetsFlutterBinding.ensureInitialized() 会确保这些系统被正确初始化,为后续的 widget 构建、渲染和交互提供基础。

2. 处理应用生命周期

WidgetsBinding 还负责管理应用的生命周期,例如应用进入后台、回到前台、暂停、恢复等状态。通过调用 WidgetsFlutterBinding.ensureInitialized(),可以确保应用的生命周期管理系统正常工作,开发者可以监听这些生命周期事件并做出相应的处理。

3. 初始化服务和插件

许多 Flutter 插件和服务依赖于 WidgetsBinding 的初始化。在调用这些插件或服务之前,必须确保 WidgetsBinding 已经初始化,否则可能会导致异常或错误。

使用场景

1. 异步操作之前

当你需要在应用启动时执行一些异步操作,如读取本地存储、初始化第三方服务等,通常需要先调用 WidgetsFlutterBinding.ensureInitialized()。例如:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() async {
  // 确保 WidgetsBinding 被初始化
  WidgetsFlutterBinding.ensureInitialized();

  // 执行异步操作,如设置系统导航栏颜色
  SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
    statusBarColor: Colors.transparent,
  ));

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const Scaffold(
        body: Center(
          child: Text('Hello, World!'),
        ),
      ),
    );
  }
}

2. 使用 Flutter 插件时

如果你使用了一些需要初始化的 Flutter 插件,也需要先调用 WidgetsFlutterBinding.ensureInitialized()。例如,使用 shared_preferences 插件来读写本地存储:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() async {
  // 确保 WidgetsBinding 被初始化
  WidgetsFlutterBinding.ensureInitialized();

  // 获取 SharedPreferences 实例
  final prefs = await SharedPreferences.getInstance();

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const Scaffold(
        body: Center(
          child: Text('Hello, World!'),
        ),
      ),
    );
  }
}

绑定机制

在 Flutter 中,绑定(Binding)是连接 Flutter 框架和底层系统的桥梁,它负责处理各种系统事件(如输入、渲染、生命周期等)并将其传递给 Flutter 应用的各个部分。WidgetsFlutterBinding 是其中一个重要的绑定类,它继承自多个基础绑定类,综合了多种功能,将 widget 层与 Flutter 引擎连接起来。

1. 单例模式

WidgetsFlutterBinding 使用了单例模式,确保在整个应用的生命周期中只有一个 WidgetsFlutterBinding 实例。这是通过静态属性 _instance 来实现的,代码示例如下:

class WidgetsFlutterBinding extends BindingBase with GestureBinding, SchedulerBinding, ServicesBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
  static WidgetsFlutterBinding? _instance;

  /// Returns an instance of the [WidgetsBinding], creating and initializing it if necessary.
  static WidgetsFlutterBinding ensureInitialized() {
    if (_instance == null) {
      WidgetsFlutterBinding();
    }
    return _instance!;
  }

  /// Initializes this [WidgetsFlutterBinding].
  WidgetsFlutterBinding() {
    assert(_instance == null);
    _instance = this;
    initInstances();
    initServiceExtensions();
    SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
    readInitialLifecycleStateFromNativeWindow();
  }
 
}

ensureInitialized() 方法中,首先检查 _instance 是否为 null。如果为 null,则创建一个新的 WidgetsFlutterBinding 实例;否则,直接返回现有的实例。

2. 初始化实例

_instancenull 时,会调用 WidgetsFlutterBinding 的构造函数。在构造函数中,会执行一系列的初始化操作:

  • initInstances():这是一个重要的方法,它会调用父类的 initInstances() 方法,依次初始化各个绑定类的实例。例如,GestureBinding 负责处理手势事件,SchedulerBinding 负责调度任务,ServicesBinding 负责处理平台消息等。这些绑定类的初始化确保了 Flutter 应用能够与底层系统进行交互。
  • initServiceExtensions():该方法用于初始化 Flutter 的服务扩展,服务扩展提供了一些额外的功能,如性能监控、调试工具等。
  • 设置生命周期消息处理程序:通过 SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage),可以监听应用的生命周期事件(如进入后台、回到前台等),并在 _handleLifecycleMessage 方法中进行相应的处理。
  • 读取初始生命周期状态readInitialLifecycleStateFromNativeWindow() 方法用于从原生窗口读取应用的初始生命周期状态,确保应用在启动时能够正确处理生命周期事件。