Not able to stop listening to stream in flutter

2,221

even if the one of the tabs is not visible the dispose will never be called, as the parent of the tab still exists on the route stack.

you have two options

  1. make the stream a broadcast stream
  2. below

rather than making the stream a BroadCast change the listener function when required like this


  //obtain the subscription only once, with a dummy listener if you prefer
  //stream.listen just sets the onData function
  var sub = stream.listen((event){});

  //just change the listener like this in the required tabs
  //tab A
  sub.onData((event) { });

  //tab B
  sub.onData((event) { });
Share:
2,221
Karan Mehta
Author by

Karan Mehta

I'm a mobile app developer having experience of working in 3 mobile technologies like Android, React Native & Flutter.

Updated on December 22, 2022

Comments

  • Karan Mehta
    Karan Mehta over 1 year

    I'm using a library for activity recognition in flutter which creates a stream for activity recognition data that comes from the sensors of the phone, I'm able to start stream but not able to stop it when tab from bottom navigation bar changes.

    I'm following this example, so now i want to have a start & stop button which can start & stop the stream listening.

    I have created it like this :

    Stream<Activity> stream;
    StreamController<Activity> streamController = new StreamController();
    
    stream = ActivityRecognition.activityUpdates();
    if(!streamController.hasListener){
          streamController.addStream(stream);
          streamController.stream.listen(onData);
      }
    
    Future<void> onData(Activity activity) async {
        String formattedDate() {
          var date = DateTime.now();
          return date.day.toString() +
              "/" +
              date.month.toString() +
              "/" +
              date.year.toString() +
              "  " +
              date.hour.toString() +
              ":" +
              date.minute.toString() +
              ":" +
              date.second.toString();
        }
    
        insertActivity(RecognizedData(
            activity: activity.type.toString(),
            confidence: activity.confidence,
            dateTime: formattedDate()));
      }
    

    And then in dispose & deactivate method i have written code like this:

    @override
      void dispose() {
        streamController.close();
        print("STREAM_CLOSED");
        super.dispose();
      }
    
      @override
      void deactivate() {
        streamController.close();
        print("STREAM_CLOSED");
        super.deactivate();
      }
    

    But it doesn't stop the streaming when the tab changes from bottom navigation bar, so when i open that tab again it shows "Bad State : Stream has already been listened to", so please help me with how to solve this.

    Thanks in advance.

    • GrahamD
      GrahamD almost 4 years
      Tabs are not pages so when you change them you are not running dispose or deactivate (I presume your print statements do not run?), I can't see if you are setting up the stream outside of initState but assume you are as it would explain the error. InitState should also not rerun when changing tabs.