You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建可供多处Widget监听的单例Stream,解决重复监听报错问题

问题根因

你代码的核心问题出在onBark getter的实现上:每次访问该属性时,都会对原始单订阅Stream重复调用asBroadcastStream()方法。对同一个单订阅流多次调用asBroadcastStream()时,第一次调用已经占用了原始流的唯一订阅名额,后续调用就会触发Bad state: Stream has already been listened to错误。

修复方案

只需要提前生成一次广播流并缓存,后续访问onBark时直接返回缓存的广播流即可,修改Dog类的实现:

class Dog {
  final StreamController _barkController = StreamController();
  // 提前缓存广播流,仅生成一次
  late final Stream _onBarkStream = _barkController.stream.asBroadcastStream();

  static final Dog _dog = Dog._();
  factory Dog() {
    return _dog;
  }
  Dog._();

  // 直接返回缓存好的广播流,不要重复调用asBroadcastStream
  Stream get onBark => _onBarkStream;

  void bark() {
    _barkController.add("woof " + DateTime.now().toString());
  }
}

额外优化建议

  • 如果你使用的是GetIt做依赖注入,不需要自己手写单例,直接通过GetIt注册单例即可,代码更简洁易维护
  • 用完StreamController后记得调用dispose方法释放资源,避免内存泄漏

内容的提问来源于stack exchange,提问作者arunized

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:15:04