isolate_runner_mixin 0.1.1
isolate_runner_mixin: ^0.1.1 copied to clipboard
A Flutter-aware Dart mixin for easily running CPU-intensive tasks, including those that use Flutter plugins, in a background isolate.
isolate_runner_mixin #
A Flutter-aware Dart mixin for easily running CPU-intensive tasks, including those that use Flutter plugins, in a background isolate.
Why use this package? #
Flutter applications run on a single thread, the UI thread. If you perform long-running or computationally intensive tasks directly on this thread, your UI can become unresponsive, leading to "jank" and a poor user experience. Dart's Isolates provide a way to run code concurrently in separate memory spaces, preventing UI blocking.
However, using raw dart:isolate APIs can be verbose, especially when dealing with Flutter plugins, which require specific initialization (BackgroundIsolateBinaryMessenger.ensureInitialized) within the background isolate.
This package provides a simple IsolateRunnerMixin that encapsulates this boilerplate, allowing you to easily offload any FutureOr<T> Function() to a background isolate.
Key Features #
Simple API: A single runInIsolate method.
Flutter Plugin Compatible: Automatically initializes BackgroundIsolateBinaryMessenger in the background isolate using the RootIsolateToken.
UI Thread Protection: Ensures heavy computations run off the main thread.
Graceful Fallback: Automatically runs tasks on the current thread if no Flutter binding is available (e.g., in pure Dart tests).
Unique Mixin Design: Integrates isolate functionality directly into your classes, providing a clean, object-oriented API that feels more natural than using top-level functions or helper classes.
Installation #
Add this to your pubspec.yaml file:
dependencies #
isolate_runner_mixin: <latest>
Then, run flutter pub get.
Usage #
Apply the Mixin #
Apply IsolateRunnerMixin to any class where you want to run tasks in a background isolate.
import 'package:isolate_runner_mixin/isolate_runner_mixin.dart';
import 'package:fast_rsa/fast_rsa.dart'; // Example plugin usage
class MyService with IsolateRunnerMixin {
// Your service logic
String _publicKey = '...'; // Example data
Future<bool> verifyData(String data, String signature) async {
// Use runInIsolate to offload the heavy work
return await runInIsolate(() async {
// This code runs in the background isolate
await Future.delayed(const Duration(milliseconds: 100)); // Simulate work
final isValid = await RSA.verifyPKCS1v15(signature, data, Hash.SHA256, _publicKey);
return isValid;
});
}
}
Top-Level/Static Functions for Heavy Work (Recommended) #
While Isolate.run can implicitly capture variables from closures, it's generally safer and more explicit to pass all necessary data to a top-level or static function that performs the heavy work. This function will then be called from within the runInIsolate's closure.
// This must be a top-level function or a static method.
// It receives all its data via explicit arguments.
import 'package:fast_rsa/fast_rsa.dart';
Future<bool> _performVerification(String data, String signature, String publicKey) async {
// This code runs in the background isolate
await Future.delayed(const Duration(milliseconds: 100)); // Simulate work
final isValid = await RSA.verifyPKCS1v15(signature, data, Hash.SHA256, publicKey);
return isValid;
}
class MyService with IsolateRunnerMixin {
String _publicKey = '...'; // Example data
Future<bool> verifyData(String data, String signature) async {
return await runInIsolate(() async {
// Call the top-level function with explicit arguments
return await _performVerification(data, signature,_publicKey);
});
}
}
Example App #
For a complete example, see the example/ directory in the package repository. The example demonstrates using the mixin to run both a CPU-intensive loop and a plugin-like task while keeping the UI responsive.
Contributing #
Feel free to open issues or pull requests on GitHub.
License #
This package is licensed under the MIT License. See the LICENSE file for details.