Middle
What is a Completer in Dart and how can it be used in Flutter development?
sobes.tech AI
Answer from AI
Completer is a class in the dart:async library that allows creating a Future and completing it later with a value or an error. It is useful when an asynchronous operation does not return a Future directly but can be notified of its completion.
import 'dart:async';
void main() async {
final completer = Completer<String>(); // Create a Completer for Future<String>
// Simulate an asynchronous operation
Future.delayed(Duration(seconds: 2), () {
// Complete the Future with a successful value
completer.complete("Operation completed successfully!");
// completer.completeError(StateError("Something went wrong!")); // Or with an error
});
print("Waiting for operation to complete...");
try {
// Get the Future from the Completer and wait for it to complete
final result = await completer.future;
print("Result: $result");
} catch (e) {
print("An error occurred: $e");
}
}
In Flutter, Completer is often used for:
- Integration with native APIs: When native code calls a callback upon operation completion,
Completercan be used to convert this into a Future in Dart. - Implementing custom asynchronous operations: When you need to create an async function that does not use existing Future-returning APIs.
- Communication between isolates: To signal the completion of work in another isolate.
Example of usage in Flutter with a native API (hypothetical):
import 'dart:async';
import 'package:flutter/services.dart';
class NativeService {
static const platform = MethodChannel('com.example/native_service');
Future<String> performNativeOperation() async {
final completer = Completer<String>();
try {
final result = await platform.invokeMethod('startOperation');
// It is assumed that native code will call 'operationCompleted'
// with the result or error, and we listen for these calls.
platform.setMethodCallHandler((call) async {
if (call.method == 'operationCompleted') {
if (call.arguments is String) {
completer.complete(call.arguments as String);
} else if (call.arguments is PlatformException) {
completer.completeError(call.arguments as PlatformException);
} else {
completer.completeError(StateError("Unknown native operation result"));
}
// Remove the handler if no longer needed
platform.setMethodCallHandler(null);
}
return true; // Indicate that the call was handled
});
} on PlatformException catch (e) {
completer.completeError(e);
}
return completer.future; // Return the Future that will be completed later
}
}
// In a widget or elsewhere:
// final service = NativeService();
// try {
// final nativeResult = await service.performNativeOperation();
// print("Native result: $nativeResult");
// } catch (e) {
// print("Native operation error: $e");
// }