There are some scenarios where screens with their respective BLoCs are frequently created and closed. So I'm somewhat concerned about memory safety of the Streams instances created in this process, because it doesn't seem they are disposed somewhere or whether they are GC-ed. This clearly depends on the specific implementation of DART libraries and flutter. So if you know about their behavior, please let me know.
These are some scenarios I have encountered.
I wonder if it is necessary to override dispose() function and explicitly close all streams in BLoCProvider. It seems existing tutorials didn't mention it.
Memory leaks occur when an object that is supposed to be garbage collected has something holding a reference to it. As more and more instances of that object are created, older instances are still being retained in the application's memory.
Add LeakNavigatorObserver to navigatorObservers in MaterialApp , it will automatically detect whether there is a memory leak in the page's Widget and its corresponding Element object. If page's Widget is a StatefulWidget , it will also be automatically checked Its corresponding State .
Bloc is a good pattern that will be suitable for almost all types of apps. It helps improve the code's quality and makes handling states in the app much more manageable. It might be challenging for someone who is just beginning to use Flutter because it uses advanced techniques like Stream and Reactive Programming.
BLoC uses the concept of Streams, or Reactive programming. This means that when a stream of events is created, subscribers can listen in on the stream of events. The subscribers are notified of new data when it is emitted into the stream. Widgets in Flutter use this stream for communication and sending data.
Streams will properly be cleaned as long as they aren't used anymore. The thing is, to simply removing the variable isn't enough to unsure it's unused. It could still run in background.
You need to call Sink.close()
so that it stops the associated StreamController
, to ensure resources can later be freed by the GC.
To do that, you have to use StatefulWidget.dispose
method:
abstract class MyBloc {
Sink foo;
Sink bar;
}
class MyWiget extends StatefulWidget {
@override
_MyWigetState createState() => _MyWigetState();
}
class _MyWigetState extends State<MyWiget> {
MyBloc bloc;
@override
void dispose() {
bloc.bar.close();
bloc.foo.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
// ...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With