深入解析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
的?counterProvider
中State
的改变又是如何更新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();
}
}
从上面的代码中我们可以看到ProviderScopeState
的build
方法返回了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();
}
}
以上代码也应证了我们对UncontrolledProviderScope
是InheritedWidget
的扩展的猜测,并且根据InheritedWidget
特性,将ProviderScope
作为顶级节点,那么其子节点也能够获取到UncontrolledProviderScope
实例。
而获取UncontrolledProviderScope
实例主要是为了获取其内部的ProviderContainer
实例container
。官方对ProviderContainer
的定义是用于保存各种Providers
的State
,并且支持重写某些特殊provider
的行为,当然我们几乎也不会直接使用到ProviderContainer
,ProviderContainer
类的内容比较多,我们在后文中也会单独列出涉及到的相关内容,以下是该过程的部分时序图。
StateProvider
首先StateProvider
是ProviderBase
的子类,基本上其他各种类似的Provider
都是ProviderBase
的子类,而且每个ProviderBase
的子类都有其对应的ProviderElementBase
子类,例如StateProvider
对应的是StateProviderElement
,StateProviderElement
又是ProviderElementBase
的子类,如下:
这里的
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
首先我们通过类图来看一下它们之间的关系:
Cusumer
继承自CusumerWidget
并重写了build(BuildContext context, WidgetRef ref)
方法,该方法向外部抛出了WidgetRef
的实例ref
,WidgetRef
是widgets
和providers
交互的关键,其中定义了watch(provider)、listen(provider)、read(provider)
等方法,而且从类图中可以看出ConsumerStatefulElement
是WidgetRef
的实现类,那么接下来我们看一下具体是如何实现的。
从上面的时序图中可以看出,
Element
(Flutter
中的Element
)在inflateWidget
方法中调用newWidget.createElement
方法创建了ConsumerStatefulElement
实例,此处的newWidget
为Consumer
实例,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);
}
}
在完成了createElement
、createState
等一系列操作后,我们继续回到Element
的inflateWidget
方法,此时继续执行了newChild.mount
,这里的newChild
即newWidget.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.initState
、state.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._element
即ConsumerStatefulElement
实例,并且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
,也重写了WidgetRef
的watch、listen、exists、read、refresh
等方法,无不与provider
息息相关,至此我们也明白了Conusmer/ConsumerWidget
与ProviderScope
、Provider
之间的关联。
ConsumerStatefulElement-watch
下面我们以watch
函数为出发点,来康一下ref
是如何从counterProvider
中获取State
实例的,counterProvider
中State
实例的改变又是如何更新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
中加入了一个以target
为key
的匿名函数(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,
);
}
}
在ProviderContainer
的listen
中直接调用了provider.addListener
,可以看到ProviderListenable
没有实现逻辑,因此我们需要到相关的实现类Provider
中查找,即全局的counterProvider
(final 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)
的结果,此处的node
即ProviderContainer
实例。
// 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
实例的创建也是使用到了外部传入的provider
和container
本身。
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
的_element
即StateProviderElement
实例,与此同时element
中的_provider、_origin、_container
也都被赋值,而后调用了element
的mount
方法。
// 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
中主要调用了buildState
,buildState
中调用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
实例,并将实例添加到_listeners
,fireImmediately
为true
直接调用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
赋值结束才执行的。
接下来让我们回到ProviderBase
中addListener
方法,此时通过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()
,看到这里还能想起是在哪里传入的么,没错就是CosumerStatefulElement
中watch
方法的return _container.listen<Res>(target, (_, __) => markNeedsBuild())
,那么大家可能也想到了State
实例值发生改变的时候应该是会调用_listener
,进而通过CosumerStatefulElement
的markNeedsBuild()
刷新对应的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
实例。
此时让我们再次回到ConsumerStatefulElement
的watch
方法,此时我们已经确定read()
执行后返回的正是final counterProvider = StateProvider((ref) => 0)
中的State
实例(0)。
以上便是通过Consumer
中ref
获取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
实例,而后调用provider
的read()
,这里需要注意下,此时的provider
是counterProvider.notifier
,通过上述代码我们可以看出notifier
是ProviderElementProxy
实例,该实例的_origin
为StateProvider
实例,_lense
为(element) {return (element as StateProviderElement<T>)._controllerNotifier;}
,而在执行read(Node node)
时首先通过node.readProviderElement(_origin)
获取element
,这个方法在之前我们已经讲过了,可以回忆一下。最终获取到的element
即StateProviderElement
实例,进而通过调用_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)
,而通过Result
和ResultData
可以看出requireState
即state
,state
正是在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++
最主要的部分也就是对于_listeners
中listenerEntry.listener(value)
的调用,那此处的listenerEntry.listener
大家还记得是什么么,让我们回到StateProviderElement
中create()
中。
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
正如我们之前所说的必然是调用CosumerStatefulElement
的markNeedsBuild()
,进而实现Consumer
的更新,进而实现Text
的更新。
最后
好了,以上就是所有的示例分析内容,不说了不说了,去规划一下鸿蒙兼容吧。。。