码农之家

flutter之State生命周期

在Flutter中,State的生命周期可以分为以下几个阶段:创建、更新和销毁。在这些阶段中,State会触发一系列生命周期方法来响应不同的事件。

  1. 创建阶段

在创建阶段中,State会触发以下生命周期方法:

  • initState:初始化State对象,通常用于初始化一些状态和数据
  • didChangeDependencies:在State对象依赖的对象发生变化时调用,通常用于获取依赖对象并更新状态
  • build:构建UI界面
  1. 更新阶段

在更新阶段中,State会触发以下生命周期方法:

  • didUpdateWidget:在Widget属性发生变化时调用,通常用于更新状态
  • setState:用于更新State对象的状态
  • build:构建UI界面
  1. 销毁阶段

在销毁阶段中,State会触发以下生命周期方法:

  • deactivate:暂时从视图树中移除,通常用于释放一些资源
  • dispose:永久从视图树中移除,通常用于释放所有资源

下面我们来详细了解一下每个生命周期方法的作用:

  1. initState

这个方法会在State对象被创建后调用,用于初始化State对象。在这个方法中,我们通常可以进行一些状态和数据的初始化操作。

  1. didChangeDependencies

这个方法会在State对象依赖的对象发生变化时调用,例如父Widget发生变化时。在这个方法中,我们通常可以获取依赖对象并更新状态。

  1. build

这个方法会在创建阶段和更新阶段都会被调用,用于构建UI界面。在这个方法中,我们通常会根据当前的状态和数据来构建UI。

  1. didUpdateWidget

这个方法会在Widget属性发生变化时调用,例如父Widget的属性发生变化时。在这个方法中,我们通常可以更新一些状态和数据。

  1. setState

这个方法会在State对象的状态发生变化时调用,用于更新状态。在这个方法中,我们通常可以更新一些状态和数据,并触发UI的重新构建。

  1. deactivate

这个方法会在State对象暂时从视图树中移除时调用,例如当页面被覆盖时。在这个方法中,我们通常可以释放一些资源,以避免内存泄漏。

  1. dispose

这个方法会在State对象永久从视图树中移除时调用,例如当页面被销毁时。在这个方法中,我们通常可以释放所有资源,以避免内存泄漏。

总之,了解State的生命周期是非常重要的,可以帮助我们更好地管理UI的状态和资源,以确保应用程序的高效性和稳定性。

didUpdateWidget方法是在更新阶段中调用的,当StatefulWidget的父Widget属性发生变化时会触发该方法。

源码实现:

复制dart
@protected
@mustCallSuper
void didUpdateWidget(covariant T oldWidget) {
  assert(() {
    if (debugPrintRebuildDirtyWidgets)
      debugPrint('didUpdateWidget ${widget.runtimeType}');
    return true;
  }());
}

可以看到,didUpdateWidget方法中调用了assert方法,用于在开发模式下输出调试信息。

同时,该方法还接收一个oldWidget参数,用于获取旧的Widget对象。我们可以通过比较旧的Widget对象和新的Widget对象来判断Widget属性是否发生了变化,从而更新一些状态和数据。

总之,理解生命周期方法的源码实现可以帮助我们更好地管理UI状态和资源,以确保应用程序的高效性和稳定性。

除了didUpdateWidget方法,其他生命周期方法的源码实现也是类似的。让我们以StatefulWidget的生命周期方法initState为例,来进一步解析其源码实现。

initState方法是在创建阶段中调用的,用于初始化State对象。在这个方法中,我们通常可以进行一些状态和数据的初始化操作。

源码实现:

复制dart
@protected
@mustCallSuper
void initState() {
  assert(_debugLifecycleState == _StateLifecycle.created);
  if (widget._debugLifecycleState != null)
    widget._debugLifecycleState!._created(this);
  if (widget.initializer != null) {
    final dynamic result = widget.initializer!();
    assert(() {
      if (result is Future) {
        throw FlutterError.fromParts(<DiagnosticsNode>[
          ErrorSummary(
            'State.initState() returned a Future.'
          ),
          ErrorDescription(
            'State.initState() must be a void method, not a Future.'
          ),
        ]);
      }
      if (result is FutureOr) {
        throw FlutterError.fromParts(<DiagnosticsNode>[
          ErrorSummary(
            'State.initState() returned a FutureOr<dynamic> type.'
          ),
          ErrorDescription(
            'State.initState() must be a void method, not a FutureOr<dynamic> type.'
          ),
        ]);
      }
      return true;
    }());
  }
}

我们可以看到,initState方法中也调用了assert方法,用于在开发模式下输出调试信息。

同时,该方法还判断了State对象的生命周期状态是否为created。

在State对象的整个生命周期中,其生命周期状态会随着不同的事件发生而改变,而_created状态表示State对象已经被创建。

在这个方法中,我们还可以通过widget对象的initializer属性来初始化State对象的状态和数据。

initializer属性是一个无参的闭包函数,它返回一个动态类型的值,可以用于在初始化State对象时执行一些逻辑操作。

didChangeDependencies方法是在创建阶段中调用的,当State对象依赖的对象发生变化时会触发该方法。在这个方法中,我们通常可以获取依赖对象并更新状态。

源码实现:

复制dart
@protected
@mustCallSuper
void didChangeDependencies() {
  assert(_debugLifecycleState == _StateLifecycle.created);
  if (_dependencies != null)
    _dependencies!.didChangeDependencies();
}

我们可以看到,didChangeDependencies方法中也调用了assert方法,用于在开发模式下输出调试信息。

同时,该方法还判断了State对象的生命周期状态是否为created。在State对象的整个生命周期中,其生命周期状态会随着不同的事件发生而改变,而_created状态表示State对象已经被创建。

在这个方法中,我们还可以获取依赖对象并更新状态。在Flutter中,State对象可以依赖于其他对象,例如InheritedWidget、MediaQuery等。当这些依赖对象发生变化时,didChangeDependencies方法就会被调用,我们可以在这个方法中获取新的依赖对象并更新状态,以保持UI的正确性和一致性。

原文链接:https://juejin.cn/post/7221821674747117605 作者:君不见999