dart_ui_isolate 1.1.1 dart_ui_isolate: ^1.1.1 copied to clipboard
Run `dart:ui` in an isolate.
dart_ui_isolate #
This plugin let you run dart:ui
in an isolate.
See this issue: https://github.com/flutter/flutter/issues/10647
FlutterEngineGroup Support #
Unlike flutter_isolate, dart_ui_isolate
supports FlutterEngineGroup
.
FlutterEngineGroup
makes spawning isolates instant. It also reduces 99% of RAM.
FlutterEngineGroup
is supported on both iOS & Android, but not macOS.
No Platform Plugin Support #
Unlike flutter_isolate, dart_ui_isolate
does not support calling platform plugins in the spawned isolate.
Why?
- Standard
Isolate
s support platform plaugins as of Flutter 3.7. You can just use a standardIsolate
. - Removing platform plugin support simplifies
dart_ui_isolate
- Platform plugins don't always work with
FlutterEngineGroup
See: https://github.com/rmawatson/flutter_isolate/pull/151
If you need to use both dart:ui
& platform plugins from the same isolate, you will need to use flutter_isolate.
DartUiIsolate API #
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 |
Usage #
To spawn a DartUiIsolate, call the spawn()
method, or the flutterCompute()
method.
Killing #
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.
MacOS #
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();
Compute Callback #
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);
}
Isolate Entry Point #
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();
}
}