flutter源码StatefulElement分析

首先,StatefulElement是一个有状态的widget在widget树中的位置。它继承自ComponentElement类,而ComponentElement是一个抽象类,它代表了一个可组合的widget,即它有子节点的能力。这表明StatefulElement也是可以有子节点的。

下面是StatefulElement类的构造函数:

StatefulElement(StatefulWidget widget)
      : _state = widget.createState(),
        super(widget) {
    assert(() {
      if (!state._debugTypesAreRight(widget)) {
        throw FlutterError.fromParts(<DiagnosticsNode>[
          ErrorSummary('StatefulWidget.createState must return a subtype of State<${widget.runtimeType}>'),
          ErrorDescription(
            'The createState function for ${widget.runtimeType} returned a state '
            'of type ${state.runtimeType}, which is not a subtype of '
            'State<${widget.runtimeType}>, violating the contract for createState.',
          ),
        ]);
      }
      return true;
    }());
    assert(state._element == null);
    state._element = this;
    assert(
      state._widget == null,
      'The createState function for $widget returned an old or invalid state '
      'instance: ${state._widget}, which is not null, violating the contract '
      'for createState.',
    );
    state._widget = widget;
    assert(state._debugLifecycleState == _StateLifecycle.created);
  }

在构造函数中,首先调用了widget的createState方法来创建一个State对象,并将它赋值给私有变量_state。同时,它通过调用父类ComponentElement的构造函数来初始化当前StatefulElement对象。

在构造函数的第一个断言中,它检查了createState方法返回的State对象是否是StatefulWidget的子类。如果不是,则抛出异常。这是因为StatefulWidget的createState方法必须返回一个与之关联的State子类的实例。在第二个断言中,它检查了State对象的_element属性是否为空,如果不为空,则抛出异常。这是因为一个State对象只能被关联到一个StatefulElement对象上。在第三个断言中,它检查了State对象的_widget属性是否为空,如果不为空,则抛出异常。这是因为State对象的_widget属性必须为空,它会在StatefulElement对象的update方法中被更新。最后,在构造函数的最后一个断言中,它检查了State对象的生命周期状态是否为created。

下面是StatefulElement类的build方法:

@override
Widget build() => state.build(this);

在build方法中,它调用了State对象的build方法来构建widget,并将当前StatefulElement对象作为参数传递给State对象的build方法。这是因为State对象需要访问StatefulElement对象的一些属性和方法,比如StatefulElement的父Element对象,以及调用markNeedsBuild方法来标记自身需要重建。

StatefulElement类还重写了reassemble方法来处理热重载(hot reload)操作。热重载是指在不重新启动应用程序的情况下,重新加载应用程序的代码并重新运行。在Flutter中,热重载是一个非常有用的开发工具,可以加快开发速度。

下面是StatefulElement类的reassemble方法:

@override
  void reassemble() {
    if (_debugShouldReassemble(_debugReassembleConfig, _widget)) {
      state.reassemble();
    }
    super.reassemble();
  }

在reassemble方法中,它首先检查是否需要重新组装(reassemble)。这是通过调用_flutterToolsGet(_kDebugReassembleConfig)方法来获取调试选项,然后与widget进行比较来确定的。如果需要重新组装,则调用State对象的reassemble方法来重新组装State。最后,它调用父类ComponentElement的reassemble方法来重新组装widget。

接下来让我们来看一下StatefulElement类的_firstBuild方法。这个方法会在StatefulElement对象第一次构建时被调用。

@override
  void _firstBuild() {
    assert(state._debugLifecycleState == _StateLifecycle.created);
    try {
      _debugSetAllowIgnoredCallsToMarkNeedsBuild(true);
      final Object? debugCheckForReturnedFuture = state.initState() as dynamic;
      assert(() {
        if (debugCheckForReturnedFuture is Future) {
          throw FlutterError.fromParts(<DiagnosticsNode>[
            ErrorSummary('${state.runtimeType}.initState() returned a Future.'),
            ErrorDescription('State.initState() must be a void method without an `async` keyword.'),
            ErrorHint(
              'Rather than awaiting on asynchronous work directly inside of initState, '
              'call a separate method to do this work without awaiting it.',
            ),
          ]);
        }
        return true;
      }());
    } finally {
      _debugSetAllowIgnoredCallsToMarkNeedsBuild(false);
    }
    assert(() {
      state._debugLifecycleState = _StateLifecycle.initialized;
      return true;
    }());
    state.didChangeDependencies();
    assert(() {
      state._debugLifecycleState = _StateLifecycle.ready;
      return true;
    }());
    super._firstBuild();
  }

在_firstBuild方法中,它首先检查State对象的生命周期状态是否为created。然后,它调用State对象的initState方法来初始化State。在initState方法中,可以进行一些初始化操作,比如获取数据、设置定时器等等。需要注意的是,initState方法必须是一个同步的、没有返回值的方法,不能包含async关键字。如果initState方法返回了Future,则会抛出异常。在调用initState方法之前,它通过调用_debugSetAllowIgnoredCallsToMarkNeedsBuild(true)方法来临时允许忽略markNeedsBuild方法的调用。

接着,它将State对象的生命周期状态设置为initialized,并调用State对象的didChangeDependencies方法。didChangeDependencies方法会在State对象的依赖关系发生变化时被调用,比如父widget的状态发生变化时。在这个方法中,可以处理一些与依赖关系相关的操作,比如获取依赖的数据、更新widget等等。

最后,它将State对象的生命周期状态设置为ready,并调用父类ComponentElement的_firstBuild方法来完成StatefulElement的第一次构建。在_firstBuild方法中,还包含了一些断言用于检查State对象的生命周期状态是否正确,以及检查initState方法是否符合要求。

总的来说,StatefulElement类的_firstBuild方法主要完成了StatefulElement的初始化和准备工作,包括调用State对象的initState方法和didChangeDependencies方法,并将State对象的生命周期状态设置为initialized和ready。

接下来让我们来看一下StatefulElement类的performRebuild方法。这个方法会在StatefulElement对象需要重建时被调用。

@override
  void performRebuild() {
    if (_didChangeDependencies) {
      state.didChangeDependencies();
      _didChangeDependencies = false;
    }
    super.performRebuild();
  }

在performRebuild方法中,它首先检查_didChangeDependencies属性是否为true。如果是,则调用State对象的didChangeDependencies方法,并将_didChangeDependencies属性置为false。didChangeDependencies方法会在State对象的依赖关系发生变化时被调用,比如父widget的状态发生变化时。在这个方法中,可以处理一些与依赖关系相关的操作,比如获取依赖的数据、更新widget等等。

接着,它调用父类ComponentElement的performRebuild方法来完成StatefulElement的重建。在performRebuild方法中,会调用StatefulElement的build方法来构建widget,并将构建出的widget添加到RenderObject树中进行绘制。

总的来说,StatefulElement类的performRebuild方法主要完成了StatefulElement的重建工作,包括调用State对象的didChangeDependencies方法和父类ComponentElement的performRebuild方法。

下面是StatefulElement类的update方法:

@override
  void update(StatefulWidget newWidget) {
    super.update(newWidget);
    final StatefulWidget oldWidget = widget;
    widget = newWidget;
    assert(() {
      if (!state._debugTypesAreRight(newWidget)) {
        throw FlutterError.fromParts(<DiagnosticsNode>[
          ErrorSummary('StatefulWidget.createState must return a subtype of State<${newWidget.runtimeType}>'),
          ErrorDescription(
            'The createState function for ${newWidget.runtimeType} returned a state '
            'of type ${state.runtimeType}, which is not a subtype of '
            'State<${newWidget.runtimeType}>, violating the contract for createState.',
          ),
        ]);
      }
      return true;
    }());
    state.widget = newWidget;
    if (oldWidget != newWidget) {
      state.didUpdateWidget(oldWidget);
    }
    rebuild();
  }

在update方法中,它首先调用了父类ComponentElement的update方法来更新widget。然后,它将旧的widget赋值给局部变量oldWidget,将新的widget赋值给widget属性,并通过一个断言来检查createState方法返回的State对象是否是newWidget的子类。

接着,它更新了State对象的widget属性,并在新旧widget不相同时调用State对象的didUpdateWidget方法,这个方法会在新旧widget不相同时被调用,用于处理widget的变化。

最后,它调用了rebuild方法来标记StatefulElement需要重建。

下面是StatefulElement类的activate方法:

@override
  void activate() {
    super.activate();
    state.activate();
    markNeedsBuild();
  }

在activate方法中,它首先调用父类ComponentElement的activate方法来激活widget。然后,它调用State对象的activate方法来激活State,并调用markNeedsBuild方法来标记StatefulElement需要重建。

下面是StatefulElement类的deactivate方法:

@override
  void deactivate() {
    state.deactivate();
    super.deactivate();
  }

在deactivate方法中,它首先调用State对象的deactivate方法来取消激活State。然后,它调用父类ComponentElement的deactivate方法来取消激活widget。

下面是StatefulElement类的unmount方法:

@override
  void unmount() {
    state.dispose();
    assert(() {
      if (debugPrintGlobalKeyedWidgetLifecycle) {
        final String? key = _widget.key?.toString() ?? '';
        print('dispose $runtimeType $key');
      }
      return true;
    }());
    super.unmount();
    _state = null;
  }

在unmount方法中,它首先调用State对象的dispose方法来释放资源。然后,它调用父类ComponentElement的unmount方法来卸载widget,最后将_state置为null。

下面是StatefulElement类的dependOnInheritedElement方法

@override
  InheritedWidget dependOnInheritedElement(Element ancestor, { Object? aspect }) {
    assert(() {
      final String? widgetName = widget.runtimeType.toString();
      if (ancestor is InheritedElement) {
        final InheritedElement inherited = ancestor;
        if (inherited.widget is! InheritedProvider<Object?>) {
          final String? ancestorName = inherited.widget.runtimeType.toString();
          throw FlutterError.fromParts(<DiagnosticsNode>[
            ErrorSummary('$widgetName created a dependency of type $aspect on ancestor of type $ancestorName.'),
            ErrorDescription(
              '$widgetName widgets cannot depend on $ancestorName widgets, '
              'directly or indirectly. Instead, they should use static '
              'Consumer widgets, subscribe to Changes using a ChangeNotifier '
              'or a similar object, or rebuild when the $ancestorName widget '
              'rebuilds.',
            ),
            ErrorSpacer(),
            DiagnosticsProperty<Element>('The offending widget is', this, style: DiagnosticsTreeStyle.errorProperty),
            DiagnosticsProperty<Element>('The ancestor in question is', ancestor, style: DiagnosticsTreeStyle.errorProperty),
          ]);
        }
        final InheritedProvider<Object?> provider = inherited.widget as InheritedProvider<Object?>;
        state._dependOnInheritedProvider(provider, aspect);
        return true;
      }
      return true;
    }());
    return super.dependOnInheritedElement(ancestor as InheritedElement, aspect: aspect);
  }

在dependOnInheritedElement方法中,它首先进行了一些断言,用于检查是否存在不正确的依赖关系。然后,它调用父类ComponentElement的dependOnInheritedElement方法来依赖于继承的widget element,并返回依赖的InheritedWidget。在此之前,它调用了State对象的_dependOnInheritedProvider方法来处理依赖关系。

最后,StatefulElement类还重写了一些其他方法,比如didChangeDependencies、toDiagnosticsNode和debugFillProperties等,这些方法用于处理StatefulElement的一些生命周期事件和调试信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值