跳到主要内容

Provider生命周期

什么时候创建并销毁我的Provider?

所有不同类型的provider经历的状态是相同的:

  • 未初始化
  • 活动中
  • 暂停
  • 已销毁

已销毁 / 未初始化

未初始化已销毁的provider不占用任何内存,因为它的状态没有初始化。 从本质上来说,它只是定义了在你需要时如何创建provider的状态。 它将一直保持这种状态,直到活动中provider被创建或由于UI中的WidgetRef 读取、观察或监听它。

创建中 -> 活动中

当读取、监听或观察未初始化的provider时,将创建其状态。

在创建期间,你的provider的构建函数将会运行。 使用回调函数所暴露的 ref 读取(read)或观察(watch)的任何provider将根据需要创建,并且将检索它们的状态。

如果在创建过程中存在任何循环依赖关系,Riverpod将抛出一个错误。 修复此错误的最佳方式是重新设计依赖项,使其具有单向数据流。

provider的状态存储在 ProviderContainer 中。在Flutter应用中,此容器位于ProviderScope widget中。

因此,尽管如何创建状态(provider)的定义是全局的,但状态实际上是本地的, 并且使用嵌套的ProviderScope widget和覆盖在UI的不同部分中有所不同。

这与flutter widget的工作方式非常相似。你只需为其定义一次, 但是可以根据需要在树的不同部分重用状态。

活动中

当你的provider为活动中时,对其状态的更改将导致依赖的provider和/或依赖的UI重新构建。

从另一个角度来看,作为响应式框架,你可以观察其他provider,以便在它的某个依赖项发生变化时重建自己。

如果你需要一些依赖于其他状态的长期状态,你可以使用Ref的 listen 方法来订阅另一个provider上的更改,而不会导致重新构建该provider。

如果你需要使用来自另一个可能有副作用的provider的状态,你可以使用Ref的[read]方法从另一个provider获取当前状态。

通常,在构造 StateNotifierChangeNotifier 类时,应该传入引用, 以允许Notifier根据需要获取依赖项的当前值。 通过使用来自Riverpod 2.0的新NotifierAsyncNotifier类,ref已经作为类的实例成员可用。

活动中 -> 暂停

当其他provider或UI不再监听活动的 provider时,它将进入暂停状态。这意味着它将不再对正在监听的provider的更改做出反应。 这是一种优化,如果你没有监听的provider,就没有必要让它保持活动状态。每个未被使用的provider都将返回到暂停状态,从而减少你的应用的计算负担。

如果你需要让provider保持活动状态以防止副作用发生,请确保在UI中应该保持活动状态的适当位置监听它。

如果你需要在provider暂停时执行一些操作,请使用ref的 onCancel 方法来注册回调函数。

当provider从暂停状态恢复到活动状态时,如果你需要执行一些操作,请使用ref的onResume方法来注册回调。

如果你想销毁状态,那么除了不占用计算资源外,还可以销毁状态的内存,请在provider上使用.autoDispose修饰符。 这将导致它在不再被使用时转换到已销毁状态,而不是暂停状态。

活动中 -> 销毁中

销毁provider有几个原因。

  • 当使用.autoDispose修饰符定义并不再被UI或其他providerg观察时
  • 当手动刷新或provider失效时
  • 当provider由于被监视的依赖项之一发生变化而被重新创建时

刷新会导致provider立即再次执行创建过程,而无效则会导致provider的下一次读取/观察导致重新构建provider。

在状态被销毁前执行操作

如果你需要在销毁provider时执行一些操作,使用ref的 onDispose 方法来注册回调函数。

下面的例子使用onDispose关闭StreamController:


Stream<int> example(ExampleRef ref) {
final streamController = StreamController<int>();

ref.onDispose(() {
// Closes the StreamController when the state of this provider is destroyed.
streamController.close();
});

return streamController.stream;
}

备注

根据所使用的provider,它可能已经处理了清理过程。 例如,StateNotifierProvider 将调用返回的 StateNotifierdispose方法。