This plugin let you run dart:ui
in an isolate.
See this issue: flutter/flutter#10647
Unlike flutter_isolate, dart_ui_isolate
supports FlutterEngineGroup
.
FlutterEngineGroup
makes spawning isolates instant. It also reduces 99% of RAM for spawned isolates.
Note: FlutterEngineGroup
is supported on both iOS & Android, but not macOS.
Unlike flutter_isolate, dart_ui_isolate
does not support calling platform plugins in the spawned isolate.
Why? As of Flutter 3.7, you can call platform plugins from normal Isolate
. Just use a normal Isolate
instead of dart_ui_isolate
.
There are a couple more advantages:
- Removing support for platform plugins makes
dart_ui_isolate
simpler. - Platform plugins don't always work well with
FlutterEngineGroup
See: rmawatson/flutter_isolate#151
If you need to use both dart:ui
& platform plugins from the same isolate, you will need to use flutter_isolate.
Android | iOS | Description | |
---|---|---|---|
DartUiIsolate.spawn() | ✅ | ✅ | spawns a new DartUiIsolate |
isolate.pause() | ✅ | ✅ | pauses the isolate |
isolate.resume() | ✅ | ✅ | resumes the isolate |
isolate.kill() | ✅ | ✅ | kills the an isolate |
flutterCompute() | ✅ | ✅ | runs code in compute callback |
To spawn a DartUiIsolate, call the spawn()
method, or the flutterCompute()
method.
DartUiIsolate
s require explict termination with kill()
.
DartUiIsolate
s are backed by a platform specific 'view', so the event loop does not automatically terminate when there is no more work left.
Due to limitations on Flutter macOS, you must put this code in your /lib/main.dart
file.
/lib/main.dart
@pragma('vm:entry-point')
void _flutterIsolateEntryPoint() => DartUiIsolate.macosIsolateInitialize();
To use an isolate for a single task (like the Flutter compute
method), use flutterCompute
:
@pragma('vm:entry-point')
Future<int> expensiveWork(int arg) async {
int result;
// lots of calculations
return result;
}
Future<int> doExpensiveWorkInBackground() async {
return await flutterCompute(expensiveWork, arg);
}
The isolate entrypoint must be a top-level function, or a class static
method.
The isolate entrypoint must decorated with @pragma('vm:entry-point')
. Otherwise the app will crash in release mode.
Top-Level Entry Point:
@pragma('vm:entry-point')
void topLevelFunction(Map<String, dynamic> args) {
// performs work in an isolate
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
DartUiIsolate.spawn(topLevelFunction, {});
super.initState();
}
Widget build(BuildContext context) {
return Container();
}
}
Class Static Entry Point:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@pragma('vm:entry-point')
static void topLevelFunction(Map<String, dynamic> args) {
// performs work in an isolate
}
@override
void initState() {
DartUiIsolate.spawn(_MyAppState.staticMethod, {});
super.initState();
}
Widget build(BuildContext context) {
return Container();
}
}
A class-level method will not work and will throw an Exception:
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
void classMethod(Map<String, dynamic> args) {
// don't do this!
}
@override
void initState() {
// this will throw NoSuchMethodError: The method 'toRawHandle' was called on null.
DartUiIsolate.spawn(classMethod, {});
super.initState();
}
Widget build(BuildContext context) {
return Container();
}
}