Where Isolate can be defined in Flutter? How to start a thread in Flutter?
You should read https://dev.to/alphamikle/why-should-you-use-isolates-in-flutter-1k5o, and look at package:isolates.
The article contrasts using main thread, compute, Isolate proper, and the isolates package, with advantages and disadvantages of each. Best article I've seen in a long time.
Also keep in mind, Java threads are data-shared, leading to possible deadlocks. Dart isolates are share-nothing, using "ports" to carefully move data between isolates, and no need for locking!
user10475643
Updated on December 28, 2022Comments
-
user10475643 over 1 year
I am a new in Flutter, so the question can be kind of obvious, but I can't find any answer on the Internet.
I have a Flutter application with some screens and I would say on the fifth screen I have a button, which should trigger some heavy computation work (converting thousands of images). On the same screen there is a progress bar and it is supposed to display the progress.
I am puzzled how to implement that technically. The triggering is happening obviously on
onPressed
of the button.- if I simply call a
Future<void>
function, then the UI is freezing completely for the time of processing, which is obviously is not desired behavior - if I put my function inside
compute
, on the firstawait
I get exceptionUnhandled Exception: Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized. If you're running an application and need to access the binary messenger before runApp() has been called (for example, during plugin initialization), then you need to explicitly call the WidgetsFlutterBinding.ensureInitialized() first.
which puzzles me, because I callWidgetsFlutterBinding.ensureInitialized()
beforerunApp()
. Anyway this method is not working.
compute(computationFunction, 'argument'); // ... static void computationFunction(String argument) async { await firstStepFunction(); // ...
- if I put my function into
Isolate.spawn
I get exceptionUnhandled Exception: Invalid argument(s): Isolate.spawn expects to be passed a static or top-level function
which is also puzzling me. I tried to make the functionstatic
and moved the function to the top level of this fifth screen module. Nothing changed. Am I supposed to start theIsolate
at themain
function? In all beautiful examples it is done like that. Can't I start theIsolate
in the middle by the button click.
Isolate.spawn(computationFunction, receivePort.sendPort); // ... void computationFunction(SendPort sendPort) async { await firstStepFunction(); // ...
In Java I think a simple
new Thread(...).start()
will do the job.But how to do it in Flutter?
Update:
In my experiments I've noticed, that neither Flutter Hot Restart nor Hot Reload are not working correctly with isolates. You need really to run again the whole app.
I managed to start
Isolate.spawn
all right ifasync
/await
keywords are removed. Off course the called function should have its synchronous version. So this does not work universally.Isolate.spawn(computationFunction, receivePort.sendPort); // ... static void computationFunction(SendPort sendPort) { // async removed firstStepFunctionSync(); // the function is replaced with its synchronous version // ...
I've found package
flutter_isolate
which allows to run the async functions:FlutterIsolate.spawn(computationFunction, argument); // ... void computationFunction(SendPort sendPort) async { await firstStepFunction(); // ...
I will try to use
flutter_isolate
package in my prototype. - if I simply call a