1

我有这个 StreamController:

StreamController<Workout> _selectedWorkoutSubject = new StreamController()

我在这样的 StreamBuilder 中听它:

StreamBuilder(
  stream: workoutBloc.selectedWorkoutStream,
  builder: (BuildContext context, AsyncSnapshot<Workout> snapshot) {
    if (snapshot.hasData) {
      return ...
    } else {
      return Text('loading...');
    }
  }
);

当我离开当前页面并返回它时,我得到了例外:Bad state: Stream has already been listened to.我知道我一次只能一次,但这不是我正在做的吗?当我离开页面时,StreamBuilder 应该收集垃圾,释放流,以便其他东西可以收听它。

或者一个 Stream 一般只能听一次(一次不是一次)?我知道我能做到

StreamController<Workout> _selectedWorkoutSubject = new StreamController.broadcast();

但我试图理解为什么它不像我最初那样工作。

4

2 回答 2

3

这不是“一次一个”。传统的非广播流只能听一次,永远。它只允许一个侦听器,当该侦听器取消时,流会自行清理并且不会再次工作。

一个传统的广播流可以被监听很多次,但是所有并发的监听器都会收到相同的事件。

大多数Stream构造函数和StreamControllers 创建传统的“单订阅”流或广播流。

添加了另一种创建可以多次收听的流的方法:Stream.multi构造函数。这样,您可以单独处理每个listen呼叫,并向他们发送您想要的任何事件,不一定是所有侦听器的相同值(每个listen呼叫都有自己的 indivudual StreamController)。

您可以使用它来实现广播流的行为,但您不必这样做。

除此之外,使用广播流是您的最佳选择。广播流控制器在停止拥有侦听器并再次开始拥有侦听器时确实会获取onCancelonListen事件,因此您可以避免在没有侦听器时进行工作。使用Stream.multi,您必须自己记录所有听众。

于 2019-02-11T08:47:18.217 回答
1

尝试几件事:

  1. 设置流构建器的初始数据
  2. 将 StreamController 更改为 BehaviorSubject (RxDart lib)

我认为第一个提示会帮助你,

于 2019-02-11T08:27:07.717 回答