How to easily cancel streams in Flutter
Flutter: automatically disposes StreamSubscription
and closes Sink
when disposing State<T>
.
In a Flutter application, when using mostlyBLoC
pattern, RxDart
, andStreams
, it is easy to forget to cancel StreamSubscription
and close Sink
/StreamController
/Subject
when Bloc or State is no longer needed. If you forgot it, it can causes memory leak, more memory consumption and other problems, especially in large applications.
Inspirited by RxSwift DisposeBag and NSObject-Rx, I have created 2 packages disposebag and flutter_disposebag, helps to cancel StreamSubscriptions
and close Sink
s automatically when disposing State<T>
.
Simple usage
- Step 1:
with DisposeBagMixin.
After mark State
class with DisposeBagMixin
, you can access to DisposeBag provided by this mixin, DisposeBag get bag
- Step 2: using extensions to add
StreamSubscription
orSink
toDisposeBag
// extension methods
Future<bool> StreamSubscription.disposedBy(DisposeBag);
Future<bool> Sink.disposedBy(DisposeBag);
Future<bool> Iterable<StreamSubscription>.disposedBy(DisposeBag);
Future<bool> Iterable<Sink>.disposedBy(DisposeBag);
Example
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_disposebag/flutter_disposebag.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with DisposeBagMixin {
final eventS = StreamController<Event>();
HomeBloc bloc;
@override
void initState() {
super.initState();
homeBloc = HomeBloc();
homeBloc.message$.listen((msg) {}).disposedBy(bag);
eventS.disposedBy(bag);
eventS.stream.listen(homeBloc.dispatch).disposedBy(bag);
}
@override
Widget build(BuildContext context) {
return Container();
}
}
When _HomePageState
disposes, DisposeBag
will cancel all StreamSubscription
s and close all Sink
s as well, no need to worry about memory leaks :)).
Have nice day. Thanks for your reading ❤. If you like my article, just follow me on medium, github and twitter.