Closed Hilbert2048 closed 1 year ago
@781flyingdutchman I submit a pull request to fix this, pls review the code to see if there is any problem.
You should simply call FileDownloader().reset Updates()
before attempting to listen to the updates stream again. A broadcast stream is not the right type of stream for these updates
Also, if I understand your description correctly, I believe your approach is incorrect. Unless you are sure your user won't leave the downloads page you're describing, you'll miss status updates that will lead to incorrect state being displayed. Generally, you should have a listener active at all times, and use those to maintain global state - not page/screen state. Your download page can then simply listen to that global state and render it on your screen.
My suggestion is to create a BLOC or singleton object that acts as the intermediary to the FileDownloader. It starts the downloads and always listens to updates so it can maintain state of all downloaded files. Your screen then renders that state, and rerenders when state changes (this is pretty standard BLOC architecture).
Hope this helps.
@781flyingdutchman
Calling "FileDownloader().resetUpdates()" before listening to the updates stream again does not fix the issue.
@781flyingdutchman
I also tried this with the BLoC architecture. Created a bloc for background downloader (lets call it BackgroundDownloaderBloc
), and a (bloc
) repository provider for FileDownloader
, above the MaterialApp
so side-effects for page states does not affect the package implementation.
Then, I opened a subscription for fileDownloader.updates.listen
which emits bloc states for task status updates of type TaskStatus
.
If you close the app, and open it again, the same set of issues as present before when navigating back and forth arrives.
It still sounds like you're starting to listen at a point that is reentered multiple times. You need to listen once, in a singleton that does not get recreated.
I think there should be another solution for this. Because there might be a situation like, we need to redirect to the first Widget in the tree. For example, sometimes we need Navigator.pushAndRemoveUntil function in order to redirect the user to the first page. Then we should be able to listen for the updates. But it gives error. Fix this please
Whenever your app is running, you should be listening to updates, unless you are 100% certain that there is no task running. Therefore, you should have your listener in a singleton-like object that lives throughout the life of your app, and where you maintain state. The fact that you may require to dopushAndRemoveUntil
doesn't change anything: if your listener is attached to a widget deep in your tree, that isn't always alive, then you should probably rethink your architecture.
Per above, you can use FileDownloader().resetUpdates()
to reset the stream before you listen, but again, you're setting yourself up for inconsistent state issues.
Sorry, I didn't understand but now I know that it works perfectly If I use it correctly. I thought if I need to update the state while listening, but outside material widget it wouldn't be initialized. However in order to start any download, the ui should be fully drawn. So now I got it, thanks :)
I am building a download app which has a screen to list all download tasks, user can enter this screen(page) and leave for multiple times.
1、listen to the stream in initState Method
2、when enter the page the second time, this will throw the error “Bad state: Stream has already been listened to”. Now even if you cancel the first subscription and subscribe again you’ll still get this error and that is by design.
https://medium.com/flutter-community/flutter-stream-basics-for-beginners-eda23e44e32f