Flutter : Bad state: Stream has already been listened to

前端 未结 11 1297
灰色年华
灰色年华 2020-12-03 04:21

    class MyPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Defaul         


        
相关标签:
11条回答
  • 2020-12-03 04:51

    StreamSplitter.split() from the async can be used for this use case

    import 'package:async/async.dart';
    ...
    
    main() {
      var process = Process.start(...);
      var stdout = StreamSplitter<List<int>>(process.stdout);
      readStdoutFoo(stdout.split());
      readStdoutBar(stdout.split());
    }
    
    readStdoutFoo(Stream<List<int>> stdout) {
      stdout.transform(utf8.decoder)...
    }
    
    readStdoutBar(Stream<List<int>> stdout) {
      stdout.transform(utf8.decoder)...
    }
    
    0 讨论(0)
  • 2020-12-03 04:55

    You should use the following.

    StreamController<...> _controller = StreamController<...>.broadcast();
    
    0 讨论(0)
  • 2020-12-03 04:58

    I have had the same issue when I used a result of Observable.combineLatest2 for StreamBuilder into Drawer:

    flutter: Bad state: Stream has already been listened to.

    As for me, the best solution has added the result of this combine to new BehaviorSubject and listen new one.

    Don't forget to listen old one !!!

    class VisitsBloc extends Object {
        Map<Visit, Location> visitAndLocation;
    
        VisitsBloc() {
            visitAndLocations.listen((data) {
                visitAndLocation = data;
            });
        }
    
        final _newOne = new BehaviorSubject<Map<Visit, Location>>();
    
        Stream<Map<Visit, Location>> get visitAndLocations => Observable.combineLatest2(_visits.stream, _locations.stream, (List<vis.Visit> visits, Map<int, Location> locations) {
            Map<vis.Visit, Location> result = {};
    
            visits.forEach((visit) {
                if (locations.containsKey(visit.skuLocationId)) {
                    result[visit] = locations[visit.skuLocationId];
                }
            });
    
            if (result.isNotEmpty) {
                _newOne.add(result);
            }
        });
    }
    

    I didn't use .broadcast because it slowed my UI.

    0 讨论(0)
  • 2020-12-03 05:01

    Just to sum up:

    The main difference is broadcast() creates a Stream listenable for multiple sources but it needs to be listened for at least one source to start emitting items.

    A Stream should be inert until a subscriber starts listening on it (using the [onListen] callback to start producing events).

    asBroadcastStream turns an existing Stream into a multi listenable one but it doesn't need to be listened to start emitting since it calls onListen() under the hood.

    0 讨论(0)
  • The problem was due to not disposing the controllers in bloc.

      void dispose() {
        monthChangedController.close();
        dayPressedController.close();
        resultController.close();
      }
    
    0 讨论(0)
提交回复
热议问题