флаттер rxdart Observable - как отписаться - PullRequest
0 голосов
/ 09 марта 2020

Вот мой пример использования: у меня установлен следующий поток:

PublishSubject<RewardedVideoAdEvent> _outVideoAdController =
PublishSubject<RewardedVideoAdEvent>();
StreamSink<RewardedVideoAdEvent> get _videoAdEvents => _outVideoAdController.sink;
Observable<RewardedVideoAdEvent> get outVideoAdEvents => _outVideoAdController.stream;

Теперь я хочу прослушать outVideoAdEvents, поэтому я добавляю это к моему StatefullWidget initState методу:

...
    if (mounted) {
      final AdMobBloc adMob =
          BlocProvider.of<AppProvider>(context).application.adMobBloc;
      adMob.outVideoAdEvents.listen((RewardedVideoAdEvent event) {
        if (event == RewardedVideoAdEvent.rewarded){
           // do something meaningfull
        }
      });
...

Пока все хорошо. Проблема, с которой я столкнулся - когда я открываю другой виджет, а затем возвращаюсь к нему, initState запускается снова и, следовательно, я добавляю другого слушателя в тот же поток. Затем, когда я в следующий раз отправлю событие в _outVideoAdController.sink, обратный вызов будет выполнен дважды.

К сожалению, в отличие от initState, dispose не выполняется каждый раз, когда я загружаю другую страницу, поэтому я не могу выяснить, как обращаться с вышеупомянутым случаем.

Обратите внимание, приложение использует rxdart: ^0.20.0

Любые советы будут с благодарностью!

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Вы можете отписаться от наблюдаемого этим методом:

_outVideoAdController?.close()
0 голосов
/ 10 марта 2020

В случае, если кто-то еще сталкивался с той же проблемой, выполните следующие действия:

  1. Добавьте личную переменную внутри виджета типа StreamSubscription<T>, где T - это ваша тип события. В моем случае это RewardedVideoAdEvent, поэтому я добавил StreamSubscription<RewardedVideoAdEvent> _videoAdSubscription;.

  2. Затем, при подписке на поток, listen вернет значение этого типа, так что просто возьмите это: _videoAdSubscription = adMob.outVideoAdEvents.listen((RewardedVideoAdEvent event) {});

  3. Наконец, когда вы хотите отписаться, просто позвоните _videoAdSubscription?.cancel();

Вот и все.

...