-
Notifications
You must be signed in to change notification settings - Fork 81
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to send class Objects in sendPort.send when using FlutterIsolate.spawn #137
Comments
Can you provide a reproducible sample project? |
@nmfisher clicking on floatingbutton would trigger the code and print the same error but if I replace import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:flutter_isolate/flutter_isolate.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
@pragma('vm:entry-point')
Future<void> someFunction(SendPort sendPort) async {
final port = ReceivePort();
sendPort.send(port.sendPort);
await for (int message in port) {
sendPort.send(Counter(message));
}
}
class Counter {
int value;
Counter(this.value);
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
final receivePort = ReceivePort();
Future<void> _incrementCounter() async {
setState(() {
_counter++;
});
final isolate =
await FlutterIsolate.spawn(someFunction, receivePort.sendPort);
receivePort.listen((message) {
if (message is SendPort) {
message.send(_counter);
} else if (message is Counter) {
print(message.value);
}
});
Future.delayed(const Duration(seconds: 1), () {
isolate.kill();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
} |
I also encountered the same problem, how to solve it, |
I opened this problem but after some testing I realized that I have the same problem indicated here. The fact that this issue has been open since April makes me think it hasn't been taken into due consideration. |
@nmfisher @rmawatson Any update on this? |
@definitelyme as I mentioned in the other linked issue, there's no update as this is fundamental to how we currently spawn isolates. If you explain what you're trying to do in more detail, I might be able to provide a workaround. |
Thanks for your reply. Basically i want to send objects to a spawned isolate using From flutter's
(see the last line) Steps to reproduce:
/// Spawn isolate using the FlutterIsolate plugin
void _spawnFluterIsolatePlugin() async {
/// Create a [ReceivePort] to send/receive messages from [FlutterIsolate] => [Main Isolate]
final ReceivePort receivePort = ReceivePort();
IsolateNameServer.registerPortWithName(receivePort.sendPort, 'main_isolate_port');
await FlutterIsolate.spawn(_isolateTask, receivePort.sendPort);
/// Optional: Listen to messages from [FlutterIsolate] ==> [Main Isolate]
receivePort.listen((message) {
print('This is the message from FlutterIsolate: $message');
});
// Wait 3 seconds before sending a message to the [FlutterIsolate]
Future.delayed(2.seconds, () {
print('Tried to send message');
IsolateNameServer.lookupPortByName('flutter_isolate_port')?.send(const IsolateMsg('Hello World!'));
});
}
/// Spawn isolate using `Isolate.spawn`
void _spawnNormalIsolate() async {
/// Create a [ReceivePort] to send/receive messages from [FlutterIsolate] => [Main Isolate]
final ReceivePort receivePort = ReceivePort();
IsolateNameServer.registerPortWithName(receivePort.sendPort, 'main_isolate_port');
await Isolate.spawn(_isolateTask, receivePort.sendPort, errorsAreFatal: true, debugName: '_spawnNormalIsolate');
/// Optional: Listen to messages from [FlutterIsolate] ==> [Main Isolate]
receivePort.listen((message) {
print('This is the message from FlutterIsolate: $message');
});
// Wait 3 seconds before sending a message to the [FlutterIsolate]
Future.delayed(2.seconds, () {
print('Tried to send message');
IsolateNameServer.lookupPortByName('flutter_isolate_port')?.send(const IsolateMsg('Hello World!'));
});
}
@pragma('vm:entry-point')
void _isolateTask(SendPort sendPort) async {
/// Create a [ReceivePort] to send/receive messages from [Main Isolate] => [FlutterIsolate]
final receivePort = ReceivePort();
IsolateNameServer.registerPortWithName(receivePort.sendPort, 'flutter_isolate_port');
/// Listen to messages from [Main Isolate] ==> [FlutterIsolate]
receivePort.listen((msg) async {
print('Received a message from main isolate: $msg');
});
}
class IsolateMsg {
final String name;
const IsolateMsg(this.name);
}
void main() {
/// ...Flutter initialization
// Try [_spawnNormalIsolate]
_spawnNormalIsolate(); // This works. Prints: "Received a message from main isolate: Instance of 'IsolateMsg'"
// // Try [_spawnFluterIsolatePlugin]
// _spawnFluterIsolatePlugin(); // Throws the exception: "[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Invalid argument: is a regular instance reachable via : Instance of 'IsolateMsg'"
} Result:Throws: Expected Outcome:Text should be printed to the console: |
What do you ultimately want to send via your SendPort? |
I want to send PS: I don't want to use Map, or List |
Yes but your IsolateMsg just contains a string, and since you can send plain strings via SendPort between FlutterIsolates without a problem, I'm assuming the actual class you want to send is more complicated. For example, could you serialize your IsolateMsg class to json, send as a plain string then deserialize on the receiving end? Also, what specifically do you need flutter_isolate for that regular isolates in the newer versions of Flutter can't do? |
Okay. Even objects like enums etc.. I just want to know why it's possible to do this with isolates created from |
It's because the current implementation of Updating the current implementation of Can you explain more about why you still need |
In my use case, I want to listen to some Firestore collections/documents inside the |
but can send the same when using Isolate.spawn from dart library.
The text was updated successfully, but these errors were encountered: