The accepted answer is out of date now, there appears to be a lot more felexibility in what you can send in Flutter 3.7. The cookbook example says:
Isolates communicate by passing messages back and forth. These messages can be primitive values, such as null, num, bool, double, or String, or simple objects such as the List in this example.
You might experience errors if you try to pass more complex objects, such as a Future or http.Response between isolates.
The example code shows this:
Future<List<Photo>> fetchPhotos(http.Client client) async {
final response = await client
.get(Uri.parse('https://jsonplaceholder.typicode.com/photos'));
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parsePhotos, response.body);
}
// A function that converts a response body into a List<Photo>.
List<Photo> parsePhotos(String responseBody) {
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Photo>((json) => Photo.fromJson(json)).toList();
}
class Photo {
final int albumId;
final int id;
final String title;
final String url;
final String thumbnailUrl;
const Photo({
required this.albumId,
required this.id,
required this.title,
required this.url,
required this.thumbnailUrl,
});
factory Photo.fromJson(Map<String, dynamic> json) {
return Photo(
albumId: json['albumId'] as int,
id: json['id'] as int,
title: json['title'] as String,
url: json['url'] as String,
thumbnailUrl: json['thumbnailUrl'] as String,
);
}
}
It's a little unclear what they mean by "simple objects such as the List" - what is a simple object?
The docs shed a bit more light on it:
The transitive object graph of message can contain the following objects:
Null
bool
int
double
String
List, Map or Set (whose elements are any of these)
TransferableTypedData
SendPort
Capability
Type representing one of these types, Object, dynamic, void or Never
If the sender and receiver isolate share the same code (e.g. isolates created via Isolate.spawn), the transitive object graph of message can contain any object, with the following exceptions:
Objects with native resources (subclasses of e.g. NativeFieldWrapperClass1). > A Socket object for example referrs internally to objects that have native resources attached and can therefore not be sent.
ReceivePort
DynamicLibrary
Finalizable
Finalizer
NativeFinalizer
Pointer
UserTag
MirrorReference
Apart from those exceptions any object can be sent. Objects that are identified as immutable (e.g. strings) will be shared whereas all other objects will be copied.
The send happens immediately and may have a linear time cost to copy the transitive object graph. The send itself doesn't block (i.e. doesn't wait until the receiver has received the message). The corresponding receive port can receive the message as soon as its isolate's event loop is ready to deliver it, independently of what the sending isolate is doing.