深入解析Flutter RiverPod一隅

808 阅读6分钟

深入解析Flutter RiverPod一隅

近期新项目在状态管理的选择上采用了RiverPod,无疑RiverPod如同Provider一样优秀,除了熟练的掌握RiverPod的使用方法以外,了解其内部的实现也同样重要,接下来让我们一探究竟。

前言

。。。算了,我们还是直接开始吧。

示例

首先我们参照RiverPod中flutter_riverpod的简单示例来逐步讲解,以下是具体的代码:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
​
// A Counter example implemented with riverpod
​
void main() {
  runApp(
    // Adding ProviderScope enables Riverpod for the entire project
    const ProviderScope(child: MyApp()),
  );
}
​
class MyApp extends StatelessWidget {
  const MyApp({super.key});
​
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Home());
  }
}
​
/// Providers are declared globally and specify how to create a state
final counterProvider = StateProvider((ref) => 0);
​
class Home extends ConsumerWidget {
  const Home({super.key});
​
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter example')),
      body: Center(
        // Consumer is a widget that allows you reading providers.
        child: Consumer(
          builder: (context, ref, _) {
            final count = ref.watch(counterProvider);
            return Text('$count');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        // The read method is a utility to read a provider without listening to it
        onPressed: () => ref.read(counterProvider.notifier).state++,
        child: const Icon(Icons.add),
      ),
    );
  }
}

通过上述代码我们可以发现以下几点:

  • ProviderScope作为项目入口;
  • 创建了一个全局的StateProvider实例counterProvider;
  • 通过ConsumerWidget中的ref读取counterProvider.notifier中的state,并进行加操作;
  • 通过Consumer中的Ref观察counterProvider获取State,然后将状态值绑定到Text上。

那么此时大家可能会有一些疑问:

  • 为什么要使用ProviderScope作为项目的顶级节点?
  • ConsumerWidget/Consumer中的Ref是什么?
  • Ref又是如何从counterProvider中获取State的?
  • counterProviderState的改变又是如何更新Text的显示内容的?

下面我们让带着这些疑问,开启探索之旅。

ProviderScope

示例中将ProviderScope作为项目入口,下面让我们来看一下ProviderScope主要有哪些内容。

@sealed
class ProviderScope extends StatefulWidget {
  /// {@macro riverpod.providerscope}
  const ProviderScope({
    super.key,
    this.overrides = const [],
    this.observers,
    this.parent,
    required this.child,
  });

  /// Read the current [ProviderContainer] for a [BuildContext].
  static ProviderContainer containerOf(
    BuildContext context, {
    bool listen = true,
  }) {
    UncontrolledProviderScope? scope;

    if (listen) {
      scope = context //
          .dependOnInheritedWidgetOfExactType<UncontrolledProviderScope>();
    } else {
      scope = context
          .getElementForInheritedWidgetOfExactType<UncontrolledProviderScope>()
          ?.widget as UncontrolledProviderScope?;
    }

    if (scope == null) {
      throw StateError('No ProviderScope found');
    }

    return scope.container;
  }
  
  final ProviderContainer? parent;

  /// The part of the widget tree that can use Riverpod and has overridden providers.
  final Widget child;

  /// The listeners that subscribes to changes on providers stored on this [ProviderScope].
  final List<ProviderObserver>? observers;

  /// Information on how to override a provider/family.
  final List<Override> overrides;

  @override
  ProviderScopeState createState() => ProviderScopeState();
}

@visibleForTesting
@sealed
@internal
class ProviderScopeState extends State<ProviderScope> {
  /// The [ProviderContainer] exposed to [ProviderScope.child].
  @visibleForTesting
  // ignore: diagnostic_describe_all_properties
  late final ProviderContainer container;
  ProviderContainer? _debugParentOwner;
  var _dirty = false;

  @override
  void initState() {
    super.initState();

    final parent = _getParent();
    assert(
      () {
        _debugParentOwner = parent;
        return true;
      }(),
      '',
    );

    container = ProviderContainer(
      parent: parent,
      overrides: widget.overrides,
      observers: widget.observers,
    );
  }

  ProviderContainer? _getParent() {
    if (widget.parent != null) {
      return widget.parent;
    } else {
      final scope = context
          .getElementForInheritedWidgetOfExactType<UncontrolledProviderScope>()
          ?.widget as UncontrolledProviderScope?;

      return scope?.container;
    }
  }

  @override
  void didUpdateWidget(ProviderScope oldWidget) {
    super.didUpdateWidget(oldWidget);
    _dirty = true;

    if (oldWidget.parent != widget.parent) {
      FlutterError.reportError(
        FlutterErrorDetails(
          library: 'flutter_riverpod',
          exception: UnsupportedError(
            'Changing ProviderScope.parent is not supported',
          ),
          context: ErrorDescription('while rebuilding ProviderScope'),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    assert(
      () {
        if (widget.parent != null) {
          // didUpdateWidget already takes care of widget.parent change
          return true;
        }
        final parent = _getParent();

        if (parent != _debugParentOwner) {
          throw UnsupportedError(
            'ProviderScope was rebuilt with a different ProviderScope ancestor',
          );
        }
        return true;
      }(),
      '',
    );
    if (_dirty) {
      _dirty = false;
      container.updateOverrides(widget.overrides);
    }

    return UncontrolledProviderScope(
      container: container,
      child: widget.child,
    );
  }

  @override
  void dispose() {
    container.dispose();
    super.dispose();
  }
}

从上面的代码中我们可以看到ProviderScopeStatebuild方法返回了UncontrolledProviderScope实例,并且ProviderScope类中提供了类方法containerOf用来查找UncontrolledProviderScope实例中的Container,此时大家可能也想到了UncontrolledProviderScope不出意外会是InheritedWidget的扩展,下面我们来看一下UncontrolledProviderScope的实现。

@sealed
class UncontrolledProviderScope extends InheritedWidget {
  /// {@macro riverpod.UncontrolledProviderScope}
  const UncontrolledProviderScope({
    super.key,
    required this.container,
    required super.child,
  });

  /// The [ProviderContainer] exposed to the widget tree.
  final ProviderContainer container;

  @override
  bool updateShouldNotify(UncontrolledProviderScope oldWidget) {
    return container != oldWidget.container;
  }

  @override
  // ignore: library_private_types_in_public_api
  _UncontrolledProviderScopeElement createElement() {
    return _UncontrolledProviderScopeElement(this);
  }
}

@sealed
class _UncontrolledProviderScopeElement extends InheritedElement {
  _UncontrolledProviderScopeElement(UncontrolledProviderScope super.widget);

  void Function()? _task;
  bool _mounted = true;

  ProviderContainer _containerOf(Widget widget) =>
      (widget as UncontrolledProviderScope).container;

  @override
  void mount(Element? parent, Object? newSlot) {
    if (kDebugMode) {
      debugCanModifyProviders ??= _debugCanModifyProviders;
    }

    vsyncOverride ??= _flutterVsync;
    super.mount(parent, newSlot);
  }

  @override
  void reassemble() {
    super.reassemble();
    assert(
      () {
        _containerOf(widget).debugReassemble();
        return true;
      }(),
      '',
    );
  }
  
  @override
  void unmount() {
    _mounted = false;
    if (kDebugMode && debugCanModifyProviders == _debugCanModifyProviders) {
      debugCanModifyProviders = null;
    }

    if (vsyncOverride == _flutterVsync) {
      vsyncOverride = null;
    }

    super.unmount();
  }

  @override
  Widget build() {
    _task?.call();
    _task = null;
    return super.build();
  }
}

以上代码也应证了我们对UncontrolledProviderScopeInheritedWidget的扩展的猜测,并且根据InheritedWidget特性,将ProviderScope作为顶级节点,那么其子节点也能够获取到UncontrolledProviderScope实例。

而获取UncontrolledProviderScope实例主要是为了获取其内部的ProviderContainer实例container。官方对ProviderContainer的定义是用于保存各种ProvidersState,并且支持重写某些特殊provider的行为,当然我们几乎也不会直接使用到ProviderContainerProviderContainer类的内容比较多,我们在后文中也会单独列出涉及到的相关内容,以下是该过程的部分时序图。

ProviderScope.png

StateProvider

首先StateProviderProviderBase的子类,基本上其他各种类似的Provider都是ProviderBase的子类,而且每个ProviderBase的子类都有其对应的ProviderElementBase 子类,例如StateProvider对应的是StateProviderElementStateProviderElement又是ProviderElementBase 的子类,如下:

Provider.png 这里的ProviderElement并不是Flutter三颗树中的Element,它是抽象类Ref<State>的实现类,final counterProvider = StateProvider((ref) => 0)表达式中的ref参数正是ProviderElementBase的子类实例,并且函数(ref) => 0赋值给了StateProvider中的_createFn属性。而且我们可以看到在StateProvider_create(ref)方法调用了_createFn并返回了T类型值(此处即为Int类型值0),因此我们能够得出一个判断,在后续获取State值时必然调用了StateProvider实例的_create(ref)方法。部分代码如下:

class StateProvider<T> extends _StateProviderBase<T>
    with AlwaysAliveProviderBase<T> {
  /// {@macro riverpod.stateprovider}
  StateProvider(
    this._createFn, {
    super.name,
    super.dependencies,
    @Deprecated('Will be removed in 3.0.0') super.from,
    @Deprecated('Will be removed in 3.0.0') super.argument,
    @Deprecated('Will be removed in 3.0.0') super.debugGetCreateSourceHash,
  }) : super(
          allTransitiveDependencies:
              computeAllTransitiveDependencies(dependencies),
        );

  /// An implementation detail of Riverpod
  @internal
  StateProvider.internal(
    this._createFn, {
    required super.name,
    required super.dependencies,
    required super.allTransitiveDependencies,
    required super.debugGetCreateSourceHash,
    super.from,
    super.argument,
  });

  /// {@macro riverpod.autoDispose}
  static const autoDispose = AutoDisposeStateProviderBuilder();

  /// {@macro riverpod.family}
  static const family = StateProviderFamilyBuilder();

  final T Function(StateProviderRef<T> ref) _createFn;

  @override
  T _create(StateProviderElement<T> ref) => _createFn(ref);

  @override
  StateProviderElement<T> createElement() => StateProviderElement._(this);

  @override
  late final AlwaysAliveRefreshable<StateController<T>> notifier =
      _notifier(this);

  @Deprecated(
    'Will be removed in 3.0.0. '
    'Use either `ref.watch(provider)` or `ref.read(provider.notifier)` instead',
  )
  @override
  late final AlwaysAliveRefreshable<StateController<T>> state = _state(this);

  /// {@macro riverpod.overridewith}
  Override overrideWith(
    Create<T, StateProviderRef<T>> create,
  ) {
    return ProviderOverride(
      origin: this,
      override: StateProvider<T>.internal(
        create,
        from: from,
        argument: argument,
        dependencies: null,
        allTransitiveDependencies: null,
        debugGetCreateSourceHash: null,
        name: null,
      ),
    );
  }
}

ConsumerWidget/Consumer

首先我们通过类图来看一下它们之间的关系:

Consumer.png Cusumer继承自CusumerWidget并重写了build(BuildContext context, WidgetRef ref)方法,该方法向外部抛出了WidgetRef的实例refWidgetRefwidgetsproviders交互的关键,其中定义了watch(provider)、listen(provider)、read(provider)等方法,而且从类图中可以看出ConsumerStatefulElementWidgetRef的实现类,那么接下来我们看一下具体是如何实现的。

ConsumerSequence.png 从上面的时序图中可以看出,ElementFlutter中的Element)在inflateWidget方法中调用newWidget.createElement方法创建了ConsumerStatefulElement实例,此处的newWidgetConsumer实例,createElement方法在ConsumerStatefulWidget中实现。

  // Element部分代码
  @protected
  @pragma('vm:prefer-inline')
  Element inflateWidget(Widget newWidget, Object? newSlot) {
      final Element newChild = newWidget.createElement();
      assert(() {
        _debugCheckForCycles(newChild);
        return true;
      }());
      newChild.mount(this, newSlot);
      assert(newChild._lifecycleState == _ElementLifecycle.active);

      return newChild;
    } finally {
      if (isTimelineTracked) {
        Timeline.finishSync();
      }
    }
  }

ConsumerStatefulWidget在构造方法中将widget赋值给了super.widget,而后StatefulWidget实例调用widget.createState创建了_ConsumerState实例,createState方法在ConsumerWidget中实现,此时StatefulElement实例的_state_ConsumerState实例,在调用super(widget)后,state._element的值为ConsumerStatefulElement实例,state._widget的值为Consumer实例。

// StatefulElement部分代码
class StatefulElement extends ComponentElement {
  /// Creates an element that uses the given widget as its configuration.
  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);
  }
}

在完成了createElementcreateState等一系列操作后,我们继续回到ElementinflateWidget方法,此时继续执行了newChild.mount,这里的newChildnewWidget.createElement()返回的ConsumerStatefulElement实例,mount的实现是在ComponentElement中。

// ComponentElement部分代码
abstract class ComponentElement extends Element {
  /// Creates an element that uses the given widget as its configuration.
  ComponentElement(super.widget);

  Element? _child;

  bool _debugDoingBuild = false;
  @override
  bool get debugDoingBuild => _debugDoingBuild;

  @override
  void mount(Element? parent, Object? newSlot) {
    super.mount(parent, newSlot);
    assert(_child == null);
    assert(_lifecycleState == _ElementLifecycle.active);
    _firstBuild();
    assert(_child != null);
  }

  void _firstBuild() {
    // StatefulElement overrides this to also call state.didChangeDependencies.
    rebuild(); // This eventually calls performRebuild.
  }
}

而后调用_firstBuild,由于StatefulElement重写了该方法,因此先调用StatefulElement中的_firstBuild

// StatefulElement部分代码
class StatefulElement extends ComponentElement {
  @override
  void _firstBuild() {
    assert(state._debugLifecycleState == _StateLifecycle.created);
    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;
    }());
    assert(() {
      state._debugLifecycleState = _StateLifecycle.initialized;
      return true;
    }());
    state.didChangeDependencies();
    assert(() {
      state._debugLifecycleState = _StateLifecycle.ready;
      return true;
    }());
    super._firstBuild();
  }
}

在完成了state.initStatestate.didChangeDependebcies等方法之后调用super._firstBuild()回到ComponentElement_firstBuild中,继续调用rebuild方法,该方法在Elament中实现。

// Element部分代码
abstract class Element extends DiagnosticableTree implements BuildContext {
	@pragma('vm:prefer-inline')
  void rebuild({bool force = false}) {
    assert(_lifecycleState != _ElementLifecycle.initial);
    if (_lifecycleState != _ElementLifecycle.active || (!_dirty && !force)) {
      return;
    }
    assert(() {
      debugOnRebuildDirtyWidget?.call(this, _debugBuiltOnce);
      if (debugPrintRebuildDirtyWidgets) {
        if (!_debugBuiltOnce) {
          debugPrint('Building $this');
          _debugBuiltOnce = true;
        } else {
          debugPrint('Rebuilding $this');
        }
      }
      return true;
    }());
    assert(_lifecycleState == _ElementLifecycle.active);
    assert(owner!._debugStateLocked);
    Element? debugPreviousBuildTarget;
    assert(() {
      debugPreviousBuildTarget = owner!._debugCurrentBuildTarget;
      owner!._debugCurrentBuildTarget = this;
      return true;
    }());
    try {
      performRebuild();
    } finally {
      assert(() {
        owner!._debugElementWasRebuilt(this);
        assert(owner!._debugCurrentBuildTarget == this);
        owner!._debugCurrentBuildTarget = debugPreviousBuildTarget;
        return true;
      }());
    }
    assert(!_dirty);
  }
  @protected
  @mustCallSuper
  void performRebuild() {
    _dirty = false;
  }
}

后调用performRebuild方法,由于StatefulElement重写了该方法,因此先执行StatefulElement中的performRebuild

// StatefulElement部分代码
class StatefulElement extends ComponentElement {
  @override
  void performRebuild() {
    if (_didChangeDependencies) {
      state.didChangeDependencies();
      _didChangeDependencies = false;
    }
    super.performRebuild();
  }
}

在执行了_didChangeDependencies判断相关操作后通过super.performRebuild回到ComponentElement

// ComponentElement部分代码
abstract class ComponentElement extends Element {
	@override
  @pragma('vm:notify-debugger-on-exception')
  void performRebuild() {
    Widget? built;
    try {
      assert(() {
        _debugDoingBuild = true;
        return true;
      }());
      built = build();
      assert(() {
        _debugDoingBuild = false;
        return true;
      }());
      debugWidgetBuilderValue(widget, built);
    } catch (e, stack) {
      _debugDoingBuild = false;
      built = ErrorWidget.builder(
        _reportException(
          ErrorDescription('building $this'),
          e,
          stack,
          informationCollector: () => <DiagnosticsNode>[
            if (kDebugMode)
              DiagnosticsDebugCreator(DebugCreator(this)),
          ],
        ),
      );
    } finally {
      // We delay marking the element as clean until after calling build() so
      // that attempts to markNeedsBuild() during build() will be ignored.
      super.performRebuild(); // clears the "dirty" flag
    }
    try {
      _child = updateChild(_child, built, slot);
      assert(_child != null);
    } catch (e, stack) {
      built = ErrorWidget.builder(
        _reportException(
          ErrorDescription('building $this'),
          e,
          stack,
          informationCollector: () => <DiagnosticsNode>[
            if (kDebugMode)
              DiagnosticsDebugCreator(DebugCreator(this)),
          ],
        ),
      );
      _child = updateChild(null, built, slot);
    }
  }
}

其中built = build()进入ConsumerStatefulElement

// ConsumerStatefulElement部分代码
class ConsumerStatefulElement extends StatefulElement implements WidgetRef {
  /// The [Element] for a [ConsumerStatefulWidget]
  ConsumerStatefulElement(ConsumerStatefulWidget super.widget);

  late ProviderContainer _container = ProviderScope.containerOf(this);
  var _dependencies =
      <ProviderListenable<Object?>, ProviderSubscription<Object?>>{};
  Map<ProviderListenable<Object?>, ProviderSubscription<Object?>>?
      _oldDependencies;
  final _listeners = <ProviderSubscription<Object?>>[];
  List<_ListenManual<Object?>>? _manualListeners;

  @override
  Widget build() {
    // TODO disallow didChangeDependencies
    try {
      _oldDependencies = _dependencies;
      for (var i = 0; i < _listeners.length; i++) {
        _listeners[i].close();
      }
      _listeners.clear();
      _dependencies = {};
      return super.build();
    } finally {
      for (final dep in _oldDependencies!.values) {
        dep.close();
      }
      _oldDependencies = null;
    }
  }
}

之后通过super.build进入StatefulElement,其中Widget build => state.build(this)进入_ConsumerState

class _ConsumerState extends ConsumerState<ConsumerWidget> {
  @override
  WidgetRef get ref => context as WidgetRef;

  @override
  Widget build(BuildContext context) {
    return widget.build(context, ref);
  }
}

此时build函数传入的context正是ConsumerStatefulElement实例,同样ref取自State中的context也正是前文中的state._elementConsumerStatefulElement实例,并且ConsumerStatefulElement作为WidgetRef的实现在此处转化成WidgetRef没有任何问题。

// State部分代码
@optionalTypeArgs
abstract class State<T extends StatefulWidget> with Diagnosticable {
  T get widget => _widget!;
  T? _widget;
  
  BuildContext get context {
    assert(() {
      if (_element == null) {
        throw FlutterError(
          'This widget has been unmounted, so the State no longer has a context (and should be considered defunct). \n'
          'Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.',
        );
      }
      return true;
    }());
    return _element!;
  }
  StatefulElement? _element;
}

widget.build(context, ref)进入Consumer后,通过_builder(context, ref, _child)ref传出。

@sealed
class Consumer extends ConsumerWidget {
  /// {@template riverpod.consumer}
  const Consumer({super.key, required ConsumerBuilder builder, Widget? child})
      : _child = child,
        _builder = builder;

  final ConsumerBuilder _builder;
  final Widget? _child;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return _builder(context, ref, _child);
  }
}

class Home extends ConsumerWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter example')),
      body: Center(
        // Consumer is a widget that allows you reading providers.
        child: Consumer(
          builder: (context, ref, _) {
            final count = ref.watch(counterProvider);
            return Text('$count');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        // The read method is a utility to read a provider without listening to it
        onPressed: () => ref.read(counterProvider.notifier).state++,
        child: const Icon(Icons.add),
      ),
    );
  }
}

通过上述一系列的操作可以看出Consumer/ConsumerWidget中的ref就是ConsumerStatefulElement,那么接下来让我们看一下ConsumerStatefulElement的具体实现。

// ConsumerStatefulElement简略代码
/// The [Element] for a [ConsumerStatefulWidget]
class ConsumerStatefulElement extends StatefulElement implements WidgetRef {
  /// The [Element] for a [ConsumerStatefulWidget]
  ConsumerStatefulElement(ConsumerStatefulWidget super.widget);

  late ProviderContainer _container = ProviderScope.containerOf(this);
  var _dependencies =
      <ProviderListenable<Object?>, ProviderSubscription<Object?>>{};
  Map<ProviderListenable<Object?>, ProviderSubscription<Object?>>?
      _oldDependencies;
  final _listeners = <ProviderSubscription<Object?>>[];
  List<_ListenManual<Object?>>? _manualListeners;

  @override
  void didChangeDependencies() {
  	...
  }

  @override
  Widget build() {
  	...
  }

  @override
  Res watch<Res>(ProviderListenable<Res> target) {}

  @override
  void unmount() {
  	...
  }

  @override
  void listen<T>(
    ProviderListenable<T> provider,
    void Function(T? previous, T value) listener, {
    void Function(Object error, StackTrace stackTrace)? onError,
  }) {
  	...
  }

  @override
  bool exists(ProviderBase<Object?> provider) {
    return ProviderScope.containerOf(this, listen: false).exists(provider);
  }

  @override
  T read<T>(ProviderListenable<T> provider) {
    return ProviderScope.containerOf(this, listen: false).read(provider);
  }

  @override
  State refresh<State>(Refreshable<State> provider) {
    return ProviderScope.containerOf(this, listen: false).refresh(provider);
  }

  @override
  void invalidate(ProviderOrFamily provider) {
    _container.invalidate(provider);
  }

  @override
  ProviderSubscription<T> listenManual<T>(
    ProviderListenable<T> provider,
    void Function(T? previous, T next) listener, {
    void Function(Object error, StackTrace stackTrace)? onError,
    bool fireImmediately = false,
  }) {
  	...
  }

从其中我们看到了熟悉的ProviderContainer实例_container,依赖_dependencies,监听_listeners,也重写了WidgetRefwatch、listen、exists、read、refresh等方法,无不与provider息息相关,至此我们也明白了Conusmer/ConsumerWidgetProviderScopeProvider之间的关联。

ConsumerStatefulElement-watch

下面我们以watch函数为出发点,来康一下ref是如何从counterProvider中获取State实例的,counterProviderState实例的改变又是如何更新Text的显示内容的。

首先我们看一下watch的具体实现。

// ConsumerStatefulElement部分代码
/// The [Element] for a [ConsumerStatefulWidget]
class ConsumerStatefulElement extends StatefulElement implements WidgetRef {
  /// The [Element] for a [ConsumerStatefulWidget]
  ConsumerStatefulElement(ConsumerStatefulWidget super.widget);

  late ProviderContainer _container = ProviderScope.containerOf(this);
  var _dependencies =
      <ProviderListenable<Object?>, ProviderSubscription<Object?>>{};
  Map<ProviderListenable<Object?>, ProviderSubscription<Object?>>?
      _oldDependencies;

  @override
  Res watch<Res>(ProviderListenable<Res> target) {
    return _dependencies.putIfAbsent(target, () {
      final oldDependency = _oldDependencies?.remove(target);

      if (oldDependency != null) {
        return oldDependency;
      }

      return _container.listen<Res>(
        target,
        (_, __) => markNeedsBuild(),
      );
    }).read() as Res;
  }
}

// map.dart
V putIfAbsent(K key, V ifAbsent());
V? remove(Object? key);

通过putIfAbsent_dependencies中加入了一个以targetkey的匿名函数(wrapped in a lambda),该匿名函数执行时,如果本身已在_oldDependencies中的话会直接从_oldDependencies中删除并添加到_dependencies中,如果不存在会通过_container.listen获取。

// ProviderContainer部分代码
@sealed
class ProviderContainer implements Node {
	@override
  ProviderSubscription<State> listen<State>(
    ProviderListenable<State> provider,
    void Function(State? previous, State next) listener, {
    bool fireImmediately = false,
    void Function(Object error, StackTrace stackTrace)? onError,
  }) {
    // TODO test always flushed provider
    return provider.addListener(
      this,
      listener,
      fireImmediately: fireImmediately,
      onError: onError,
      onDependencyMayHaveChanged: null,
    );
  }
}

// foundation.dart
// ProviderListenable部分代码
@immutable
mixin ProviderListenable<State> {
  /// Starts listening to this transformer
  ProviderSubscription<State> addListener(
    Node node,
    void Function(State? previous, State next) listener, {
    required void Function(Object error, StackTrace stackTrace)? onError,
    required void Function()? onDependencyMayHaveChanged,
    required bool fireImmediately,
  });

  /// Obtains the result of this provider expression without adding listener.
  State read(Node node);

  ProviderListenable<Selected> select<Selected>(
    Selected Function(State value) selector,
  ) {
    return _ProviderSelector<State, Selected>(
      provider: this,
      selector: selector,
    );
  }
}

ProviderContainerlisten中直接调用了provider.addListener,可以看到ProviderListenable没有实现逻辑,因此我们需要到相关的实现类Provider中查找,即全局的counterProviderfinal counterProvider = StateProvider((ref) => 0);)。

// ProviderBase部分代码
@immutable
abstract class ProviderBase<State> extends ProviderOrFamily
    with ProviderListenable<State>
    implements ProviderOverride, Refreshable<State> {
  /// A base class for _all_ providers.
  const ProviderBase({
    required super.name,
    required this.from,
    required this.argument,
    required this.debugGetCreateSourceHash,
    required super.dependencies,
    required super.allTransitiveDependencies,
  });

  @override
  ProviderBase<Object?> get _origin => this;

  @override
  ProviderBase<Object?> get _override => this;

  @internal
  final DebugGetCreateSourceHash? debugGetCreateSourceHash;

  /// If this provider was created with the `.family` modifier, [from] is the `.family` instance.
  @override
  final Family<Object?>? from;

  /// If this provider was created with the `.family` modifier, [argument] is
  /// the variable that was used.
  final Object? argument;

  @override
  ProviderSubscription<State> addListener(
    Node node,
    void Function(State? previous, State next) listener, {
    required void Function(Object error, StackTrace stackTrace)? onError,
    required void Function()? onDependencyMayHaveChanged,
    required bool fireImmediately,
  }) {
    onError ??= Zone.current.handleUncaughtError;

    final element = node.readProviderElement(this);

    element.flush();
    if (fireImmediately) {
      handleFireImmediately(
        element.getState()!,
        listener: listener,
        onError: onError,
      );
    }

    element._onListen();

    return node._listenElement(
      element,
      listener: listener,
      onError: onError,
    );
  }
}

ProviderBase中我们可以看到首先执行了final element = node.readProviderElement(this),后返回了node._listenElement( element, listener: listener, onError: onError)的结果,此处的nodeProviderContainer实例。

// ProviderContainer部分代码
@sealed
class ProviderContainer implements Node {
  final Map<ProviderBase<Object?>, _StateReader> _stateReaders;

	@override
	ProviderElementBase<State> readProviderElement<State>(
    ProviderBase<State> provider,
  ) {
    final reader = _getStateReader(provider);
    return reader.getElement() as ProviderElementBase<State>;
  }
  
  _StateReader _getStateReader(ProviderBase<Object?> provider) {
    final currentReader = _stateReaders[provider];
    if (currentReader != null) return currentReader;

    _StateReader getReader() {
      // The provider had no existing state and no override, so we're
      // mounting it on the root container.
      final reader = _StateReader(
        origin: provider,
        // If a provider did not have an associated StateReader then it is
        // guaranteed to not be overridden
        override: provider,
        container: _root ?? this,
        isDynamicallyCreated: true,
      );
      return reader;
    }

    return _stateReaders[provider] = getReader();
  }
}

以上readProviderElement、_getStateReader、getReader函数的实现比较复杂,此处提取了主要的代码,有需要的可以看一下源码,可以看到readProviderElement最终来自_stateReaders中的_StateReader实例下的getElement()_StateReader实例的创建也是使用到了外部传入的providercontainer本身。

class _StateReader {
  _StateReader({
    required this.origin,
    required this.override,
    required this.container,
    required this.isDynamicallyCreated,
  });

  final ProviderBase<Object?> origin;
  ProviderBase<Object?> override;
  final ProviderContainer container;

  /// Whether the [_StateReader] was created on first provider read instead of
  /// at the creation of the [ProviderContainer]
  final bool isDynamicallyCreated;

  ProviderElementBase<Object?>? _element;

  ProviderElementBase<Object?> getElement() => _element ??= _create();

  ProviderElementBase<Object?> _create() {
    if (origin == _circularDependencyLock) {
      throw CircularDependencyError._();
    }
    _circularDependencyLock ??= origin;
    try {
      final element = override.createElement()
        .._provider = override
        .._origin = origin
        .._container = container
        ..mount();

      element.getState()!.map<void>(
        // ignore: avoid_types_on_closure_parameters
        data: (ResultData<Object?> data) {
          for (final observer in container._observers) {
            runTernaryGuarded(
              observer.didAddProvider,
              origin,
              data.state,
              container,
            );
          }
        },
        error: (error) {
          for (final observer in container._observers) {
            runTernaryGuarded(
              observer.didAddProvider,
              origin,
              null,
              container,
            );
          }
          for (final observer in container._observers) {
            runQuaternaryGuarded(
              observer.providerDidFail,
              origin,
              error.error,
              error.stackTrace,
              container,
            );
          }
        },
      );
      return element;
    } finally {
      if (_circularDependencyLock == origin) {
        _circularDependencyLock = null;
      }
    }
  }
}

通过上述代码我们可以看到,getElement()返回的是_element,如果_element为空的情况下会调用_create()创建,具体由override.createElement()返回,此时的override正是Provider实例,此时让我们回想一下之前声明的全局Provider实例(final counterProvider = StateProvider((ref) => 0);),终于是在这里让我们看到了createElement的调用。

// StateProvider部分代码
class StateProvider<T> extends _StateProviderBase<T>
    with AlwaysAliveProviderBase<T> {
  /// {@macro riverpod.stateprovider}
  StateProvider(
    this._createFn, {
    super.name,
    super.dependencies,
    @Deprecated('Will be removed in 3.0.0') super.from,
    @Deprecated('Will be removed in 3.0.0') super.argument,
    @Deprecated('Will be removed in 3.0.0') super.debugGetCreateSourceHash,
  }) : super(
          allTransitiveDependencies:
              computeAllTransitiveDependencies(dependencies),
        );

  @override
  StateProviderElement<T> createElement() => StateProviderElement._(this);
}

那么_StateReader_elementStateProviderElement实例,与此同时element中的_provider、_origin、_container也都被赋值,而后调用了elementmount方法。

// ProviderElementBase部分代码
abstract class ProviderElementBase<State> implements Ref<State>, Node {
	/// Called the first time a provider is obtained.
  @protected
  @mustCallSuper
  void mount() {
    _mounted = true;
    ...
    buildState();
    ...
  }
  /// Invokes [create] and handles errors.
  void buildState() {
    ProviderElementBase<Object?>? debugPreviouslyBuildingElement;
    final previousDidChangeDependency = _didChangeDependency;
    _didChangeDependency = false;
		...
    _didBuild = false;
    try {
      // TODO move outside this function?
      _mounted = true;
      create(didChangeDependency: previousDidChangeDependency);
    } catch (err, stack) {
      ...
      _state = Result.error(err, stack);
    } finally {
      _didBuild = true;
			...
      assert(
        getState() != null,
        'Bad state, the provider did not initialize. Did "create" forget to set the state?',
      );
    }
  }
  
  @visibleForOverriding
  @protected
  void create({required bool didChangeDependency});
}

通过上面的代码我们可以看到在mount中主要调用了buildStatebuildState中调用create(didChangeDependency: previousDidChangeDependency),而且StateProviderElement重写了该方法。

// StateProviderElement部分代码
/// The element of [StateProvider].
class StateProviderElement<T> extends ProviderElementBase<T>
    implements StateProviderRef<T> {
  StateProviderElement._(_StateProviderBase<T> super._provider);

  @override
  StateController<T> get controller => _controllerNotifier.value;
  final _controllerNotifier = ProxyElementValueNotifier<StateController<T>>();

  final _stateNotifier = ProxyElementValueNotifier<StateController<T>>();

  void Function()? _removeListener;

  @override
  void create({required bool didChangeDependency}) {
    final provider = this.provider as _StateProviderBase<T>;
    final initialState = provider._create(this);

    final controller = StateController(initialState);
    _controllerNotifier.result = Result.data(controller);

    _removeListener = controller.addListener(
      fireImmediately: true,
      (state) {
        _stateNotifier.result = _controllerNotifier.result;
        setState(state);
      },
    );
  }
}

首先我们可以看到该方法先获取了StateProvider实例,并且调用了该实例的_create方法,还记得我们在“StateProvider”那节讲的要获取State值的话必然会调用_create方法么,那么在此时获取到正是State实例,并且通过该实例创建了StateController实例controller,而后通过controller创建Result实例,并将Result实例赋值给_controllerNotifier.result,最后调用controller.addListener,并将结果赋值给_removeListener.

// StateController部分代码
/// A [StateNotifier] that allows modifying its [state] from outside.
///
/// This avoids having to make a [StateNotifier] subclass for simple scenarios.
class StateController<T> extends StateNotifier<T> {
  /// Initialize the state of [StateController].
  StateController(super._state);

  // Remove the protected status
  @override
  T get state => super.state;

  @override
  set state(T value) => super.state = value;

  T update(T Function(T state) cb) => state = cb(state);
}

// StateNotifier部分代码
abstract class StateNotifier<T> {
  /// Initialize [state].
  StateNotifier(this._state);

  final _listeners = LinkedList<_ListenerEntry<T>>();

  bool _mounted = true;

  /// Whether [dispose] was called or not.
  bool get mounted => _mounted;

  StreamController<T>? _controller;

  /// A broadcast stream representation of a [StateNotifier].
  Stream<T> get stream {
    _controller ??= StreamController<T>.broadcast();
    return _controller!.stream;
  }

  T _state;
  
  @protected
  T get state {
    assert(_debugIsMounted(), '');
    return _state;
  }

  @protected
  set state(T value) {
    ...
  }

  /// If a listener has been added using [addListener] and hasn't been removed yet.
  bool get hasListeners {
    assert(_debugIsMounted(), '');
    return _listeners.isNotEmpty;
  }

  RemoveListener addListener(
    Listener<T> listener, {
    bool fireImmediately = true,
  }) {
    assert(() {
      if (!_debugCanAddListeners) {
        throw ConcurrentModificationError();
      }
      return true;
    }(), '');
    assert(_debugIsMounted(), '');
    final listenerEntry = _ListenerEntry(listener);
    _listeners.add(listenerEntry);
    try {
      assert(_debugSetCanAddListeners(false), '');
      if (fireImmediately) {
        listener(state);
      }
    } catch (err, stack) {
      listenerEntry.unlink();
      onError?.call(err, stack);
      rethrow;
    } finally {
      assert(_debugSetCanAddListeners(true), '');
    }

    return () {
      if (listenerEntry.list != null) {
        listenerEntry.unlink();
      }
    };
  }
}

class _ListenerEntry<T> extends LinkedListEntry<_ListenerEntry<T>> {
  _ListenerEntry(this.listener);

  final Listener<T> listener;
}

可以看到controller.addListener主要通过listener创建_ListenerEntry实例,并将实例添加到_listenersfireImmediatelytrue直接调用listener(state),即将StateProviderElement_controllerNotifier.result赋值给_stateNotifier.result,并执行setState(state)

// ProviderElementBase部分代码
abstract class ProviderElementBase<State> implements Ref<State>, Node {
  /// {@macro riverpod.provider_element_base}
  ProviderElementBase(this._provider);

  bool _didBuild = false;

  /* STATE */
  Result<State>? _state;

  @protected
  void setState(State newState) {
    assert(
      () {
        _debugDidSetState = true;
        return true;
      }(),
      '',
    );
    final previousResult = getState();
    final result = _state = ResultData(newState);

    if (_didBuild) {
      _notifyListeners(result, previousResult);
    }
  }
  
  @protected
  @visibleForTesting
  Result<State>? getState() => _state;
}

可以看到正是此时StateProviderElement实例的_state才有了值ResultData实例。

注:由于此时_didBuild为false,因此并不会执行_notifyListeners(result, previousResult),也就不会引发相关widget的更新,_didBuild值的改变可以翻看上面ProviderElementBase当中的buildState()_didBuild变更为true是在_state赋值结束才执行的。

接下来让我们回到ProviderBaseaddListener方法,此时通过final element = node.readProviderElement(this)获取到了StateProviderElement实例,继续执行node._listenElement( element, listener: listener, onError: onError)

// ProviderContainer部分代码
@sealed
class ProviderContainer implements Node {
  @override
  ProviderSubscription<State> _listenElement<State>(
    ProviderElementBase<State> element, {
    required void Function(State? previous, State next) listener,
    required void Function(Object error, StackTrace stackTrace) onError,
  }) {
    final sub = _ExternalProviderSubscription<State>._(
      element,
      listener,
      onError: onError,
    );

    element._externalDependents.add(sub);

    return sub;
  }
}

该方法主要创建了_ExternalProviderSubscription实例,并将该实例sub添加到了element._externalDependents中,之后返回sub

// _ExternalProviderSubscription部分代码
class _ExternalProviderSubscription<State>
    implements ProviderSubscription<State> {
  _ExternalProviderSubscription._(
    this._listenedElement,
    this._listener, {
    required this.onError,
  });

  final void Function(State? previous, State next) _listener;
  final ProviderElementBase<State> _listenedElement;
  final void Function(Object error, StackTrace stackTrace) onError;
  var _closed = false;

  @override
  void close() {
    _closed = true;
    _listenedElement._externalDependents.remove(this);
    _listenedElement._onRemoveListener();
  }
}

与此同时_ExternalProviderSubscription实例sub中的_listenedElement赋值StateProviderElement实例,_listener赋值(_, __) => markNeedsBuild(),看到这里还能想起是在哪里传入的么,没错就是CosumerStatefulElementwatch方法的return _container.listen<Res>(target, (_, __) => markNeedsBuild()),那么大家可能也想到了State实例值发生改变的时候应该是会调用_listener,进而通过CosumerStatefulElementmarkNeedsBuild()刷新对应的Widget

那么现在我们回到watch方法,_dependencies.putIfAbsent(target, V ifAbsent())我们现在知道了是返回了_ExternalProviderSubscription实例,紧接着调用了该实例的read方法。

class _ExternalProviderSubscription<State>
    implements ProviderSubscription<State> {
  _ExternalProviderSubscription._(
    this._listenedElement,
    this._listener, {
    required this.onError,
  });

  final void Function(State? previous, State next) _listener;
  final ProviderElementBase<State> _listenedElement;
  final void Function(Object error, StackTrace stackTrace) onError;
  
  @override
  State read() {
    if (_closed) {
      throw StateError(
        'called ProviderSubscription.read on a subscription that was closed',
      );
    }
    return _listenedElement.readSelf();
  }
}

该方法通过_listenedElement.readSelf()来读取相关内容。

// ProviderElementBase部分代码
abstract class ProviderElementBase<State> implements Ref<State>, Node {
  /// {@macro riverpod.provider_element_base}
  ProviderElementBase(this._provider);
  
  @protected
  @visibleForTesting
  Result<State>? getState() => _state;
  
  @protected
  State get requireState {
		...
    final state = getState();
    if (state == null) {
      throw StateError('Tried to read the state of an uninitialized provider');
    }

    return state.when(
      error: throwErrorWithCombinedStackTrace,
      data: (data) => data,
    );
  }
  
  /// Returns the currently exposed by a provider
  ///
  /// May throw if the provider threw when creating the exposed value.
  State readSelf() {
    flush();

    return requireState;
  }
}

/// The data case
@internal
class ResultData<State> implements Result<State> {
  /// The data case
  ResultData(this.state);

  /// The state
  final State state;

  @override
  bool get hasState => true;

  @override
  State? get stateOrNull => state;

  @override
  State get requireState => state;

  @override
  R map<R>({
    required R Function(ResultData<State> data) data,
    required R Function(ResultError<State>) error,
  }) {
    return data(this);
  }

  @override
  R when<R>({
    required R Function(State data) data,
    required R Function(Object error, StackTrace stackTrace) error,
  }) {
    return data(state);
  }

  @override
  bool operator ==(Object? other) =>
      other is ResultData<State> &&
      other.runtimeType == runtimeType &&
      other.state == state;

  @override
  int get hashCode => Object.hash(runtimeType, state);
}

能够看到最终通过state.when(error: throwErrorWithCombinedStackTrace, data: (data) => data)获取到了ResultData中的state实例。

此时让我们再次回到ConsumerStatefulElementwatch方法,此时我们已经确定read()执行后返回的正是final counterProvider = StateProvider((ref) => 0)中的State实例(0)。

以上便是通过Consumerref获取State的所有经过,那么现在我们还有最后一个问题,如何通过改变State实例值来引起使用State实例的widget更新。

State值更新

class Home extends ConsumerWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(title: const Text('Counter example')),
      body: Center(
        // Consumer is a widget that allows you reading providers.
        child: Consumer(
          builder: (context, ref, _) {
            final count = ref.watch(counterProvider);
            return Text('$count');
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        // The read method is a utility to read a provider without listening to it
        onPressed: () => ref.read(counterProvider.notifier).state++,
        child: const Icon(Icons.add),
      ),
    );
  }
}

下面我们主要来看一下ref.read(counterProvider.notifier).state++执行后主要发生些什么。

// ConsumerStatefulElement部分代码
class ConsumerStatefulElement extends StatefulElement implements WidgetRef {
  /// The [Element] for a [ConsumerStatefulWidget]
  ConsumerStatefulElement(ConsumerStatefulWidget super.widget);
  ...
  @override
  T read<T>(ProviderListenable<T> provider) {
    return ProviderScope.containerOf(this, listen: false).read(provider);
  }
}

// ProviderContainer部分代码
@sealed
class ProviderContainer implements Node {
  ...
  Result read<Result>(
    ProviderListenable<Result> provider,
  ) {
    return provider.read(this);
  }
}

// StateProvider部分代码
class StateProvider<T> extends _StateProviderBase<T>
    with AlwaysAliveProviderBase<T> {
  ...

  @override
  late final AlwaysAliveRefreshable<StateController<T>> notifier =
      _notifier(this);
}

// state_provider.dart
ProviderElementProxy<T, StateController<T>> _notifier<T>(
  _StateProviderBase<T> that,
) {
  return ProviderElementProxy<T, StateController<T>>(
    that,
    (element) {
      return (element as StateProviderElement<T>)._controllerNotifier;
    },
  );
}

// ProviderElementProxy部分代码
@internal
class ProviderElementProxy<Input, Output>
    with ProviderListenable<Output>, AlwaysAliveProviderListenable<Output>
    implements AlwaysAliveRefreshable<Output> {
  const ProviderElementProxy(this._origin, this._lense);

  @override
  final ProviderBase<Input> _origin;
  final ProxyElementValueNotifier<Output> Function(
    ProviderElementBase<Input> element,
  ) _lense;

  ... 
  
  @override
  Output read(Node node) {
    final element = node.readProviderElement(_origin);
    element.flush();
    element.mayNeedDispose();
    return _lense(element).value;
  }
}

首先我们看到还是通过ProviderScope.containerOf(this, listen: false)获取ProviderContainer实例,而后调用providerread(),这里需要注意下,此时的providercounterProvider.notifier,通过上述代码我们可以看出notifierProviderElementProxy实例,该实例的_originStateProvider实例,_lense(element) {return (element as StateProviderElement<T>)._controllerNotifier;},而在执行read(Node node)时首先通过node.readProviderElement(_origin)获取element,这个方法在之前我们已经讲过了,可以回忆一下。最终获取到的elementStateProviderElement实例,进而通过调用_lense(element)获取到StateProviderElement实例的_controllerNotifier,继续取_controllerNotifier实例的value

// ProxyElementValueNotifier部分代码
@internal
class ProxyElementValueNotifier<T> extends _ValueListenable<T> {
  /// Directly obtain the value exposed, grafully handling cases where
  /// [result] is null or in error state.
  T get value {
    final result = _result;
    if (result == null) {
      throw StateError('Trying to read an uninitialized value.');
    }
    return result.requireState;
  }
  ...
}

// StateProviderElement部分代码
class StateProviderElement<T> extends ProviderElementBase<T>
    implements StateProviderRef<T> {
  StateProviderElement._(_StateProviderBase<T> super._provider);

  @override
  StateController<T> get controller => _controllerNotifier.value;
  final _controllerNotifier = ProxyElementValueNotifier<StateController<T>>();

  final _stateNotifier = ProxyElementValueNotifier<StateController<T>>();

  void Function()? _removeListener;

  @override
  void create({required bool didChangeDependency}) {
    final provider = this.provider as _StateProviderBase<T>;
    final initialState = provider._create(this);

    final controller = StateController(initialState);
    _controllerNotifier.result = Result.data(controller);

    _removeListener = controller.addListener(
      fireImmediately: true,
      (state) {
        _stateNotifier.result = _controllerNotifier.result;
        setState(state);
      },
    );
  }
  ...
}

// Result部分代码
@immutable
@internal
abstract class Result<State> {
  /// The data case
  // coverage:ignore-start
  factory Result.data(State state) = ResultData;
  ...
}

// ResultData部分代码
@internal
class ResultData<State> implements Result<State> {
  /// The data case
  ResultData(this.state);

  /// The state
  final State state;

  @override
  State get requireState => state;
}

通过ProxyElementValueNotifier得知value值取自_result.requireState,而此处的_result是在StateProviderElement中执行create时创建的Result.data(controller),而通过ResultResultData可以看出requireStatestatestate正是在StateController(initialState)实例,那也就意味着我们通过ref.read(counterProvider.notifier)获取到的正是该实例。

class StateController<T> extends StateNotifier<T> {
  /// Initialize the state of [StateController].
  StateController(super._state);

  // Remove the protected status
  @override
  T get state => super.state;

  @override
  set state(T value) => super.state = value;

  T update(T Function(T state) cb) => state = cb(state);
}

abstract class StateNotifier<T> {
  /// Initialize [state].
  StateNotifier(this._state);

  final _listeners = LinkedList<_ListenerEntry<T>>();

	...

  T _state;

  @protected
  T get state {
    assert(_debugIsMounted(), '');
    return _state;
  }

  @protected
  set state(T value) {
    assert(_debugIsMounted(), '');
    final previousState = _state;
    _state = value;

    /// only notify listeners when should
    if (!updateShouldNotify(previousState, value)) {
      return;
    }

    _controller?.add(value);

    final errors = <Object>[];
    final stackTraces = <StackTrace?>[];
    for (final listenerEntry in _listeners) {
      try {
        listenerEntry.listener(value);
      } catch (error, stackTrace) {
        errors.add(error);
        stackTraces.add(stackTrace);

        if (onError != null) {
          onError!(error, stackTrace);
        } else {
          Zone.current.handleUncaughtError(error, stackTrace);
        }
      }
    }
    if (errors.isNotEmpty) {
      throw StateNotifierListenerError._(errors, stackTraces, this);
    }
  }
}

那么对于state++最主要的部分也就是对于_listenerslistenerEntry.listener(value)的调用,那此处的listenerEntry.listener大家还记得是什么么,让我们回到StateProviderElementcreate()中。

class StateProviderElement<T> extends ProviderElementBase<T>
    implements StateProviderRef<T> {
  StateProviderElement._(_StateProviderBase<T> super._provider);
  
  @override
  void create({required bool didChangeDependency}) {
    _removeListener = controller.addListener(
      fireImmediately: true,
      (state) {
        _stateNotifier.result = _controllerNotifier.result;
        setState(state);
      },
    );
  }
}

listener调用后会执行setState(state),此时我们再来看一下ProviderElementBase中的实现。

abstract class ProviderElementBase<State> implements Ref<State>, Node {
  @protected
  void setState(State newState) {
    assert(
      () {
        _debugDidSetState = true;
        return true;
      }(),
      '',
    );
    final previousResult = getState();
    final result = _state = ResultData(newState);
​
    if (_didBuild) {
      _notifyListeners(result, previousResult);
    }
  }
  
  void _notifyListeners(
    Result<State> newState,
    Result<State>? previousStateResult, {
    bool checkUpdateShouldNotify = true,
  }) {
    assert(
      () {
        if (_debugSkipNotifyListenersAsserts) return true;
​
        assert(
          _debugCurrentlyBuildingElement == null ||
              _debugCurrentlyBuildingElement == this,
          '''
Providers are not allowed to modify other providers during their initialization.
​
The provider ${_debugCurrentlyBuildingElement!.origin} modified $origin while building.
''',
        );
​
        debugCanModifyProviders?.call();
        return true;
      }(),
      '',
    );
​
    final previousState = previousStateResult?.stateOrNull;
​
    // listenSelf listeners do not respect updateShouldNotify
    newState.map(
      data: (newState) {
        final onChangeSelfListeners = _onChangeSelfListeners;
        if (onChangeSelfListeners != null) {
          for (var i = 0; i < onChangeSelfListeners.length; i++) {
            Zone.current.runBinaryGuarded(
              onChangeSelfListeners[i],
              previousState,
              newState.state,
            );
          }
        }
      },
      error: (newState) {
        final onErrorSelfListeners = _onErrorSelfListeners;
        if (onErrorSelfListeners != null) {
          for (var i = 0; i < onErrorSelfListeners.length; i++) {
            Zone.current.runBinaryGuarded(
              onErrorSelfListeners[i],
              newState.error,
              newState.stackTrace,
            );
          }
        }
      },
    );
​
    if (checkUpdateShouldNotify &&
        previousStateResult != null &&
        previousStateResult.hasState &&
        newState.hasState &&
        !updateShouldNotify(
          previousState as State,
          newState.requireState,
        )) {
      return;
    }
​
    final listeners = _externalDependents.toList(growable: false);
    final subscribers = _subscribers.toList(growable: false);
    newState.map(
      data: (newState) {
        for (var i = 0; i < listeners.length; i++) {
          Zone.current.runBinaryGuarded(
            listeners[i]._listener,
            previousState,
            newState.state,
          );
        }
        for (var i = 0; i < subscribers.length; i++) {
          Zone.current.runBinaryGuarded(
            subscribers[i].listener,
            previousState,
            newState.state,
          );
        }
      },
      error: (newState) {
        for (var i = 0; i < listeners.length; i++) {
          Zone.current.runBinaryGuarded(
            listeners[i].onError,
            newState.error,
            newState.stackTrace,
          );
        }
        for (var i = 0; i < subscribers.length; i++) {
          Zone.current.runBinaryGuarded(
            subscribers[i].onError,
            newState.error,
            newState.stackTrace,
          );
        }
      },
    );
​
    for (var i = 0; i < _providerDependents.length; i++) {
      _providerDependents[i]._markDependencyChanged();
    }
​
    for (final observer in _container._observers) {
      runQuaternaryGuarded(
        observer.didUpdateProvider,
        provider,
        previousState,
        newState.stateOrNull,
        _container,
      );
    }
​
    for (final observer in _container._observers) {
      newState.map(
        data: (_) {},
        error: (newState) {
          runQuaternaryGuarded(
            observer.providerDidFail,
            provider,
            newState.error,
            newState.stackTrace,
            _container,
          );
        },
      );
    }
  }
}

值得注意的是此时的_build已经是true了(回想一下上面获取State实例的过程),那么_notifyListeners也会执行,此时我们重点来看一下这几行代码。

final listeners = _externalDependents.toList(growable: false);
for (var i = 0; i < listeners.length; i++) {
  Zone.current.runBinaryGuarded(
    listeners[i]._listener,
    previousState,
    newState.state,
);

runBinaryGuarded方法的第一个参数是action,后两个参数作为action的参数,并执行action,而此处的action是来自_externalDependents中每个实例的_listener,而我们在通过ref获取State实例时有分析到,_externalDependents_ExternalProviderSubscription实例的集合,此时调用_ExternalProviderSubscription实例的_listener正如我们之前所说的必然是调用CosumerStatefulElementmarkNeedsBuild(),进而实现Consumer的更新,进而实现Text的更新。

最后

好了,以上就是所有的示例分析内容,不说了不说了,去规划一下鸿蒙兼容吧。。。