flutterblocinherited-widgetflutter-provider

Flutter- Understanding the lifecycle of Provider, Bloc and when to dispose the stream


Need to understand when we should Bloc pattern and life cycle of Bloc (how to release objects holding memory)

I have a screen where I am fetching the data from the server and data will be used for a single screen only. I am using Bloc pattern to show the data.

When using the Bloc pattern, I have a screen where I am using StatelessWidget. I am trying to dispose of the stream on 'WillPopScope'. Once disposed of, the stream cannot be used anymore. Because visiting the same screen result in a crash as I have wrapped my MaterialApp with the Bloc.

  1. created a stream
    final _leaderBoardList = StreamController<List<dynamic>>.broadcast();
  1. disposing stream
    dispose() {
      print('_leaderBoardList disposed');
      _leaderBoardList.close();
    }
  1. wrapping Material App within the provider:
    LeaderBoardProvider(
        child: MaterialApp(
        title: 'Table View Fetch',
        theme: ThemeData(
          primarySwatch: Colors.teal,
        ),
        home: HomeScreen(),
      ),
      );
  1. Statelesswidget 'WillPopScope', I have commented dispose of code as currently bloc is created once as I understood:
  Widget build(BuildContext context) {

    print(' ListView fetch Build called');
    final bloc = LeaderBoardProvider.of(context);
    bloc.fetchLeaderBoards();
    return WillPopScope(
      onWillPop: () async {
        //bloc.dispose();
        return true;
      },
      child: bodyStack(context, bloc),
    );
  }

The first Question, Suppose I create a broadcast stream and remove dispose of code in 'WillPopScope', then everything works as expected but I think, this way, my Bloc hold a memory for app lifetime.

Second Question, How to handle such cases in which data is used within a screen. Is Bloc pattern recommended for this situation?


Solution

  • You should not dispose BLoC within WillPopScope.

    It is the job of your "Provider" to handle the disposal of your BLoC: It should close streams when the provider widget is removed from the tree.

    This is achieved by your Provider being a StatefulWidget (with an internal private InheritedWidget to expose the BLoC) and overriding dispose method.

    See Flutter: How to correctly use an Inherited Widget? for an example (it's not related to BLoC and doesn't have a dispose, but the idea is similar).