Will StreamBuilder auto off the stream in stateless widget?
Asked Answered
S

4

14

When i using BLOC in Flutter , for Example:

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);
      },
    );
  }
}

This is a Stateless widget and don't have dispose() method there;

and how could i off the stream or will it auto off the stream when this widget destroyed?

Shipshape answered 30/1, 2019 at 8:40 Comment(2)
"off the stream"? what do you mean by that? StreamController.close()?Overburden
@Overburden yep. that isShipshape
P
1

You are passing a stream into a Stateless widget, you should close the stream overriding the dispose method of the subclassed State class associated to the Stateful widget where you have the instance of the stream. Also, in this widget, you have to check if the snapshot.data is null (and return for example a Container()) or you get an error since you are not passing an initialData to the StreamBuilder.

Portiere answered 30/1, 2019 at 9:12 Comment(3)
"overriding the dispose method" - in StatefulWidget? dispose() is a State's methodOverburden
Sorry, you're right, I meant on the subclass of State associated with the Statuful widget.Portiere
And how can i close the stream from Observable inside stream builder or stateless widget ? i have known how to close the BehaviorSubject's streamShipshape
H
10

No, it won't close the Stream, but it will close the StreamSubscription that is used to build the Widget.

If the Stream is not going to be used for anything else, the best would be to dispose the Stream somehow (by wrapping it on a StatefulWidget or by using a BlocProvider approach).

If you are using a Stream somewhere else or you will use the Stream in the future you don't need to worry about leaking memory for its use on a StreamBuilder. As long as you dispose it whenever everyone else stops using it.

The StreamBuilder itself extends from StreamBuilderBase which is a StatefulWidget, and it handles the StreamSubscription with its own dispose method.

This is an excerpt from the async.dart library.

/// 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;
    }
  }
}

As you can see, the StreamSubscription is initialized on the initState and automatically canceled on the dispose call of the State, so the subscription used here will be always closed and you don't need to worry about it.

Harty answered 22/12, 2019 at 1:3 Comment(0)
N
5

No, it won't auto close. In general the owner of the stream is the one who manages the stream state.

A good solution in my opinion is to make a stateful widget own your BLoCs and close the streams in its dispose method.

This article shows a possible way to implement this, have a look at the BlocProvider class.

Noyes answered 30/1, 2019 at 9:19 Comment(0)
W
5

In Stateless widget, the StreamBuilder itself will "auto-off" when the widget will be removed from the Widget tree. You don't have to handle anything.

BUT, if you have a StreamController which sends the snapshots you should close it manually when you're done.

Warfold answered 7/11, 2019 at 13:37 Comment(0)
P
1

You are passing a stream into a Stateless widget, you should close the stream overriding the dispose method of the subclassed State class associated to the Stateful widget where you have the instance of the stream. Also, in this widget, you have to check if the snapshot.data is null (and return for example a Container()) or you get an error since you are not passing an initialData to the StreamBuilder.

Portiere answered 30/1, 2019 at 9:12 Comment(3)
"overriding the dispose method" - in StatefulWidget? dispose() is a State's methodOverburden
Sorry, you're right, I meant on the subclass of State associated with the Statuful widget.Portiere
And how can i close the stream from Observable inside stream builder or stateless widget ? i have known how to close the BehaviorSubject's streamShipshape

© 2022 - 2024 — McMap. All rights reserved.