Flutter 的生命周期,略知一二

1. 前言

生命周期是一个组件加载到卸载的整个周期,熟悉生命周期可以让我们在合适的时机做该做的事情,例如:APP 正在播放视频,当 APP 被切换到后台,则这个时候最好是暂停视频。

Flutter 的生命周期可以分为两个部分:

  • Widget 的生命周期
  • APP 的生命周期

2. Widget 的生命周期

Flutter 里的 Widget 分为 StatelessWidget 和 StatefulWidget 两种,这两种 Widget 的生命周期是不一样的,具体如下讲解。

2.1 StatelessWidget 的生命周期

StatelessWidget 用于不需要维护状态的场景,它通常在 build() 中通过嵌套其它 Widget 来构建 UI,在构建过程中会递归的构建其嵌套的 Widget。所以 StatelessWidget 的生命周期只有一个相关的方法,就是 build() 。

build() 是用来创建 Widget 的,但因为 build() 在每次界面刷新的时候都会调用,所以不要在 build() 里写业务逻辑,可以把业务逻辑写到 StatelessWidget 的构造函数里。

2.2 StatefulWidget 的生命周期

StatefulWidget 与 StatelessWidget 最大的不同就是一个 StatefulWidget 类会对应一个 State 类。State 表示与其对应的 StatefulWidget 要维护的状态。而 StatefulWidget 的生命周期就和 State 息息相关,或者也可以这样说,StatefulWidget 的生命周期就是 State 的生命周期。

StatefulWidget 的生命周期如下图所示:
Flutter 的生命周期,略知一二_第1张图片

下面我们来看看各个回调函数:

  • initState():当 Widget 第一次插入到 Widget 树时会被调用,对于每一个State对象,Flutter Framework 只会调用一次该回调。所以,通常在该回调中做一些一次性的操作,如状态初始化、订阅子树的事件通知等。不能在该回调中调用 BuildContext.dependOnInheritedWidgetOfExactType(该方法用于在 Widget 树上获取离当前 Widget 最近的一个父级 InheritFromWidget),原因是在初始化完成后,Widget树中的InheritFromWidget 也可能会发生变化,所以正确的做法应该在在 build() 或 didChangeDependencies() 中调用它。
  • didChangeDependencies():当 State 对象的依赖发生变化时会被调用,例如:在之前 build() 中包含了一个 InheritedWidget,然后在之后的 build() 中 InheritedWidget 发生了变化,那么此时 InheritedWidget 的子 Widget 的 didChangeDependencies() 回调都会被调用。典型的场景是当系统语言 Locale 或应用主题改变时,Flutter Framework 会通知 Widget 调用此回调。
  • build():此回调主要是用于构建 Widget 子树的,会在如下场景被调用:
  1. 在调用 initState() 之后;
  2. 在调用 didUpdateWidget() 之后;
  3. 在调用 setState() 之后;
  4. 在调用 didChangeDependencies() 之后;
  5. 在 State 对象从树中一个位置移除后(会调用 deactivate )又重新插入到树的其它位置之后。
  • reassemble():此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release 模式下永远不会被调用。
  • didUpdateWidget():在 Widget 重新构建时,Flutter Framework 会调用 Widget.canUpdate 来检测 Widget 树中同一位置的新旧节点,然后决定是否需要更新,如果 Widget.canUpdate 返回 true 则会调用此回调。正如之前所述,Widget.canUpdate 会在新旧 Widget 的 key 和 runtimeType 同时相等时会返回 true,也就是说在新旧 widget 的 key 和 runtimeType 同时相等时,didUpdateWidget() 就会被调用。
  • deactivate():当 State 对象从树中被移除时,会调用此回调。在一些场景下,Flutter Framework 会将 State 对象重新插到树中,如包含此 State 对象的子树在树的一个位置移动到另一个位置时(可以通过 GlobalKey 来实现)。如果移除后没有重新插入到树中则紧接着会调用 dispose() 方法。
  • dispose():当 State 对象从树中被永久移除时调用。通常在此回调中释放资源。

3. APP 的生命周期

在前言举了个例子:APP 正在播放视频,当 APP 被切换到后台,则这个时候最好是暂停视频。想实现这个功能,单单使用 Widget 的生命周期是不行的,还得借助 APP 的生命周期。

我们可以通过在 Widget 绑定 WidgetsBindingObserver 并监听 didChangeAppLifecycleState() 的变化事件来监听生命周期。

可以被观察的生命周期事件有:

  • inactive:APP 处于非活跃状态并且不接收用户输入。这个事件只适用于 iOS,Android 上没有对应的事件。
  • paused:APP 当前对用户不可见,无法响应用户输入,并运行在后台。这个事件对应于 Android 中的 onPause()。
  • resumed:APP 对用户可见并且可以响应用户的输入。这个事件对应于 Android 中的 onPostResume()。
  • suspending:APP 暂时被挂起。这个事件对应于 Android 中的 onStop; iOS 上由于没有对应的事件,因此不会触发此事件。

想要了解这些状态含义的更多细节,请查看 AppLifecycleStatus 文档。


如果想进一步交流和学习的同学,可以加一下QQ群哦!

Android开发者群号:371529514

你可能感兴趣的:(Flutter,Flutter,生命周期)