StreamBuilder 会在无状态小部件中自动关闭流吗?
Posted
技术标签:
【中文标题】StreamBuilder 会在无状态小部件中自动关闭流吗?【英文标题】:Will StreamBuilder auto off the stream in stateless widget? 【发布时间】:2019-06-23 11:40:33 【问题描述】:当我在 Flutter 中使用 BLOC 时,例如:
class StreamText extends StatelessWidget
StreamText(
this.stream,
this.style,
);
final Stream<dynamic> stream;
final TextStyle style;
@override
Widget build(BuildContext context)
return StreamBuilder<dynamic>(
stream: stream,
builder: (context, snapshot)
return Text(snapshot.data.toString(), style: style);
,
);
这是一个无状态小部件,没有dispose()
方法;
当这个小部件被破坏时,我怎么能关闭流,或者它会自动关闭流?
【问题讨论】:
"off the stream"
?你是什么意思? StreamController.close()
?
@pskink 是的。那是
【参考方案1】:
不,它不会关闭Stream
,但会关闭用于构建小部件的StreamSubscription
。
如果Stream
不用于其他任何用途,最好以某种方式处置Stream
(通过将其包装在StatefulWidget
上或使用BlocProvider
方法)。
如果您在其他地方使用Stream
,或者您将来将使用Stream
,则无需担心在StreamBuilder
上使用它会导致内存泄漏。只要您在其他人停止使用它时丢弃它。
StreamBuilder
本身扩展自 StreamBuilderBase
,这是一个 StatefulWidget
,它使用自己的 dispose
方法处理 StreamSubscription
。
这是来自async.dart
库的摘录。
/// State for [StreamBuilderBase].
class _StreamBuilderBaseState<T, S> extends State<StreamBuilderBase<T, S>>
StreamSubscription<T> _subscription;
@override
void initState()
//...
_subscribe();
@override
void dispose()
_unsubscribe();
super.dispose();
void _subscribe()
if (widget.stream != null)
_subscription = widget.stream.listen((T data)
//...
void _unsubscribe()
if (_subscription != null)
_subscription.cancel();
_subscription = null;
如你所见,StreamSubscription
在initState
上初始化,在dispose
状态调用上自动取消,所以这里使用的订阅会一直关闭,你不用担心它。
【讨论】:
【参考方案2】:不,它不会自动关闭。通常,流的所有者是管理流状态的人。
我认为一个好的解决方案是让有状态小部件拥有您的 BLoC,并在其 dispose
方法中关闭流。
This article 显示了一种可能的实现方式,请查看BlocProvider
类。
【讨论】:
【参考方案3】:在无状态小部件中,当小部件从小部件树中移除时,StreamBuilder 本身将“自动关闭”。您无需处理任何事情。
但是,如果您有一个发送快照的 StreamController,您应该在完成后手动关闭它。
【讨论】:
【参考方案4】:您正在将流传递到无状态小部件,您应该关闭流,覆盖与您拥有流实例的有状态小部件关联的子类 State 类的 dispose
方法。此外,在此小部件中,您必须检查 snapshot.data
是否为 null(并返回例如 Container()
),否则您会收到错误,因为您没有将 initialData
传递给StreamBuilder
.
【讨论】:
"overriding the dispose method"
- 在StatefulWidget
? dispose()
是State
的方法
对不起,你是对的,我的意思是与 Statuful 小部件关联的 State 的子类。
我怎样才能关闭来自 Observable 内部流构建器或无状态小部件的流?我知道如何关闭 BehaviorSubject 的流以上是关于StreamBuilder 会在无状态小部件中自动关闭流吗?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 在无状态小部件中动态地将项目添加到 ListView
在 StreamBuilder 中使用 Selector (Provider) 时不必要的小部件重建