From flutter-skills
Executes long-running tasks in background isolates to keep the UI responsive. Use when performing heavy computations or parsing large datasets.
npx claudepluginhub gsmlg-dev/code-agent --plugin flutter-skillsThis skill uses the workspace's default tool permissions.
- [Core Concepts](#core-concepts)
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
Dart utilizes a single-threaded execution model driven by an Event Loop (comparable to the iOS main loop). By default, all Flutter application code runs on the Main Isolate.
async/await): Use for non-blocking I/O tasks (network requests, file access). The Event Loop continues processing other events while waiting for the Future to complete.Apply the following conditional logic to determine the correct concurrency approach:
async/await on the Main Isolate.async/await on the Main Isolate.Isolate.run().Isolate.spawn() with ReceivePort and SendPort.Use this workflow to fetch and display non-blocking asynchronous data.
Task Progress:
async keyword.Future<T> from the function.await keyword to yield execution until the operation completes.FutureBuilder<T> (or StreamBuilder for streams).ConnectionState.waiting, hasError, and hasData states within the builder.Use this workflow for one-off, CPU-intensive tasks using Dart 2.19+.
Task Progress:
Isolate.run() passing the callback.await the result of Isolate.run() in the Main Isolate.Use this workflow for persistent background processes requiring continuous bidirectional communication.
Task Progress:
ReceivePort on the Main Isolate to listen for messages.Isolate.spawn(), passing the ReceivePort.sendPort as the initial message.ReceivePort.SendPort back to the Main Isolate via the initial port.SendPort in the Main Isolate for future message dispatching.ReceivePort instances to handle incoming messages.// 1. Define the async operation
Future<String> fetchUserData() async {
await Future.delayed(const Duration(seconds: 2)); // Simulate network I/O
return "User Data Loaded";
}
// 2. Consume in the UI
Widget build(BuildContext context) {
return FutureBuilder<String>(
future: fetchUserData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Text('Result: ${snapshot.data}');
}
},
);
}
Isolate.run)import 'dart:isolate';
import 'dart:convert';
// 1. Define the heavy computation callback
// Note: Adhering to the strict single-argument signature requirement.
List<dynamic> decodeHeavyJson(String jsonString) {
return jsonDecode(jsonString) as List<dynamic>;
}
// 2. Offload to a worker isolate
Future<List<dynamic>> processDataInBackground(String rawJson) async {
// Isolate.run spawns the isolate, runs the computation, returns the value, and exits.
final result = await Isolate.run(() => decodeHeavyJson(rawJson));
return result;
}
ReceivePort / SendPort)import 'dart:isolate';
class WorkerManager {
late SendPort _workerSendPort;
final ReceivePort _mainReceivePort = ReceivePort();
Isolate? _isolate;
Future<void> initialize() async {
// 1. Spawn isolate and pass the Main Isolate's SendPort
_isolate = await Isolate.spawn(_workerEntry, _mainReceivePort.sendPort);
// 2. Listen for messages from the Worker Isolate
_mainReceivePort.listen((message) {
if (message is SendPort) {
// First message is the Worker's SendPort
_workerSendPort = message;
_startCommunication();
} else {
// Subsequent messages are data payloads
print('Main Isolate received: $message');
}
});
}
void _startCommunication() {
// Send data to the worker
_workerSendPort.send("Process this data");
}
// 3. Worker Isolate Entry Point
static void _workerEntry(SendPort mainSendPort) {
final workerReceivePort = ReceivePort();
// Send the Worker's SendPort back to the Main Isolate
mainSendPort.send(workerReceivePort.sendPort);
// Listen for incoming tasks
workerReceivePort.listen((message) {
print('Worker Isolate received: $message');
// Perform work and send result back
final result = "Processed: $message";
mainSendPort.send(result);
});
}
void dispose() {
_mainReceivePort.close();
_isolate?.kill();
}
}