Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:ui' Class: Path)
Asked Answered
R

4

11

Can anyone tell me whats wrong in this code?

void onPressed() async {
    //Navigator.pushNamed(context, "/screen2", arguments: []);
    var receivePort = ReceivePort();
    await Isolate.spawn(gotoNext, [receivePort.sendPort]);
    final msg = await receivePort.first;
    print(msg);
  }

  void gotoNext(List<dynamic> args) {
    SendPort sendPort = args[0];
    log(args.toString());
    Isolate.exit(sendPort, "OK");
  }

E/flutter (12062): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:ui' Class: Path)

Romy answered 9/3, 2022 at 8:11 Comment(9)
this the official doc which I have followed. They are saying we can only pass primitive data type but I am getting Error with the similar code.Romy
Even this code also generating the same problem. void onPressed() async { await Isolate.spawn(gotoNext, "OK"); } void gotoNext(String args) { log(args); }Romy
where are you sending Path object?Bloomington
I am not sending bro. Thats why I am also unable to track the root cause of the problem. I have simply calling the onPressed Function on a TextButton Tap.Romy
>E/flutter (12519): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:ui' Class: Path) E/flutter (12519): #0 Isolate._spawnFunction (dart:isolate-patch/isolate_patch.dart:395:25) E/flutter (12519): #1 Isolate.spawn (dart:isolate-patch/isolate_patch.dart:375:7) E/flutter (12519): #2 _Screen1State.onPressed (package:practice/screen_1.dart:32:19) E/flutter (12519): #3 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:989:21)Romy
i used that code: void onPressed() async { var receivePort = ReceivePort(); await Isolate.spawn(gotoNext, [receivePort.sendPort]); final msg = await receivePort.first; print('received >$msg<'); } void gotoNext(List<dynamic> args) { SendPort sendPort = args[0]; print('>input parameters: $args<'); Isolate.exit(sendPort, "OK"); } and this is what i see on the logs after calling onPressed function: [+5088 ms] flutter: >input parameters: [SendPort]< [ +12 ms] flutter: received >OK<Bloomington
Can you please let me know your flutter and dart version. cos I am using latest one.Romy
Flutter 2.11.0-0.1.pre • channel beta • https://github.com/flutter/flutter.git Framework • revision b101bfe32f (3 weeks ago) • 2022-02-16 07:36:54 -0800 Engine • revision e355993572 Tools • Dart 2.17.0 (build 2.17.0-69.2.beta) • DevTools 2.10.0-dev.1Bloomington
Actually it is not running inside any Widget class. can you guide me how I can achieve this now ?Romy
H
28

Hii There is a mistake in your code. As far as I know from the official documentation The callback method for an Isolate should be a top level function or a static method. So there are two solution for this problem.

Solution 1. declare callback function as top level function.

class MyHomePage extends StatelessWidget {
  final String title;

  const MyHomePage({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: TextButton(
        child: const Text("Run Isolate"),
        onPressed: _onPressed,
      ));
    );
  }

  // Callback function for Text Button Event this should be a class member
  void _onPressed() async {
    var receivePort = ReceivePort();
    // Here runMyIsolate methos should be a top level function
    await Isolate.spawn(runMyIsolate, [receivePort.sendPort, "My Custom Message"]);
    print(await receivePort.first);
  }
}


// We declare a top level function here for an isolated callback function
void runMyIsolate(List<dynamic> args) {
  var sendPort = args[0] as SendPort;
  print("In runMyIsolate ");
  Isolate.exit(sendPort, args);
}

Solution 2. instead this top level function we can declare this function as a static function for the same class, consider below example.

    class MyHomePage extends StatelessWidget {
  final String title;

  const MyHomePage({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: TextButton(
        child: const Text("Run Isolate"),
        onPressed: _onPressed,
      ));
    );
  }

  // Callback function for Text Button Event this should be a class member
  void _onPressed() async {
    var receivePort = ReceivePort();
    // Here runMyIsolate methos should be a top level function
    await Isolate.spawn(runMyIsolate, [receivePort.sendPort, "My Custom Message"]);
    print(await receivePort.first);
  }
  
  // We declare a static function here for an isolated callback function
  static void runMyIsolate(List<dynamic> args) {
    var sendPort = args[0] as SendPort;
    print("In runMyIsolate ");
    Isolate.exit(sendPort, args);
  }
}
Habitancy answered 14/3, 2022 at 3:8 Comment(2)
Yes Now it is working for me Thanks!Romy
Good to hear that.Habitancy
E
4

I had the same issue today. Turns out the code was not supposed to run inside a widget class, the examples use them outside. Let me know how it goes.

Essy answered 9/3, 2022 at 20:59 Comment(1)
Exactly you are right! It is working in main thread but not from a Widget class. void main() async { runApp(MyApp()); var receivePort = ReceivePort(); await Isolate.spawn(gotoNext, [receivePort.sendPort]); final msg = await receivePort.first; print('received >$msg<'); } void gotoNext(List<dynamic> args) { SendPort sendPort = args[0]; print('>input parameters: $args<'); Isolate.exit(sendPort, "OK"); }Romy
G
0

arg is List<dynamic> not List<SendPort> so code is not valid

SendPort sendPort = args[0];

please try, if arg[0] is SendPort:

void _readAndParseJson(List<dynamic> args) async {
  SendPort? responsePort;
  final dynamic _responsePort = args[0];

  if (_responsePort != null && _responsePort is SendPort) {
    responsePort = _responsePort;
  }
  String? fileName;
  final dynamic _fileName = args[1];
  if (_fileName != null && _fileName is String) {
    fileName = _fileName;
  }
  final fileData = await File(fileName).readAsString();
  final result = jsonDecode(fileData) as Map<String, dynamic>;
  Isolate.exit(responsePort, result);
}
Grenade answered 9/3, 2022 at 8:30 Comment(10)
But List<SendPort> will not be the primitive type? Also I have tried to Pass Map, String and int value but problem was remains.Romy
check this documentation provided here.Romy
pls try: ``` SendPort sendPort = args[0] as SendPort; ```Synagogue
This was an Unnecessary cast bro. Also Not working.Romy
@VarunVerma see my editSynagogue
@VarunVerma add "final result = jsonDecode(fileData) as Map<String, dynamic>;"Synagogue
Nothing is helping bro.. feeling hopeless now.Romy
Is this example working for you ?Romy
maybe you used jsonDecode and Isolate.exit wrong waySynagogue
i don't know what you want to do, in this case i wouldn't use "result" like thatSynagogue
I
0

In my case, The reason is because I passed argument Object too complicated to heavy task.

 final isolate = await Isolate.spawn<List<dynamic>>(
    getIncidentListIsolate,
    [receivePort.sendPort, _affairService]);

_affairService is one complicated object. I replace with String, it it works fine.

Incalescent answered 15/9, 2023 at 11:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.