Exactly why and when are StreamController constructor functions onListen, onPause, onResume, and onCancel called?

186 Views Asked by At

In Dart/Flutter, I have a StreamController defined like this:

MyEventStreamer() {
    _controller = StreamController<TimedEvent>(
        onListen: _startStream,
        onResume: () {
          throw UnimplementedError();
        },
        onPause: () {
          throw UnimplementedError();
        },
        onCancel: _stopStream);

    _calculateEventTimes();
  }

The reason I have the throws is that I don't want onPause or onResume to be used... and I want to throw an error in case I forget this later.

However, since these are apparently not called explicitly (and the docs don't seem to describe when they are called), I'm concerned that these may be called by the system under certain unknown circumstances... such as lifecycle events on mobile when the app is backgrounded, etc... which would be bad.

Is this a legitimate concern -- or are these methods never called by anything other than code the programmer wrote?

1

There are 1 best solutions below

2
Rahul On
  1. OnListen - When there is a listener attached.
  2. OnCancel - When listener cancels listening to the events.

There are few scenarios where pause/resume is called.

  1. If you create a stream but don't want any event to emit until there is at least one listener. This way, all the events prior to the first listener is buffered and sent to the attached listener. Here you create a stream, pause it and call it's resume once there is onListen called.
  2. While using asyncExpand/asyncMap where each event is transformed into another event as per user's provided convert method. Each event is passed to asyncExpand/asyncMap to get new event which could take some time (in rare case). While these converter methods haven't returned their values, stream should not emit more values and it should buffer new events.
  3. Maybe you are connected to a websocket or firebase and you want to not listen to any events when app is in background, you can call pause/resume to defer data once app is in foreground.

There could be other use cases but these are the use-cases provided in flutter framework I am aware of.