Search code examples
flutterdartdart-isolates

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


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)


Solution

  • 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);
      }
    }