如何创建可供多处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
相关产品推荐
相关产品推荐

