3

I am trying to unzip a file with compute as follows.

class FileDownloader{

  void downloadCompleteZip(Function(double) listenerFunction){
      Map<String, dynamic> map = {
        'fileRoot': localPath,
        "filePath": completeZipLocalPath,
        "listener": listenerFunction,
        "unzipPerc": unzipPerc
      };

      await compute(unzipCompleteZipToDisk, map);
  }
}
void unzipCompleteZipToDisk(Map<String, dynamic> params) async {}

When i call the downloadCompleteZip function i get the following error:

Invalid argument(s): Illegal argument in isolate message : (object is a closure - Function '':.)

My types for variables in map are, String and Function. I think the problem is that im trying to pass a function inside map here:

"listener": listenerFunction,

My downloadCompleteZip function is longer, for the sake of example i simplified it. I really need to pass the listener key as it sends messages to update UI. How may i solve this issue of functions not being able to pass within a map inside compute?

Also, kindly please dont suggest third party lib solutions. I have seen that libs like this can help. I am trying to keep 3rd party dependencies as low as possible.

cs guy
  • 926
  • 2
  • 13
  • 33
  • i guess thats the only way. Seems like ill have to work for additional several hours :) – cs guy Oct 14 '20 at 19:53
  • Does this answer your question? [Invalid argument(s): Illegal argument in isolate message : (object is a closure - Function 'createDataList':.)](https://stackoverflow.com/questions/51998995/invalid-arguments-illegal-argument-in-isolate-message-object-is-a-closure) – Akif Oct 14 '20 at 20:42
  • No it doesnt, ive seen it. its unrelevant to my question. – cs guy Oct 14 '20 at 20:56
  • @pskink i think its impossible to send a function with SendPort. The documentation says "The content of message can be: primitive values (null, num, bool, double, String), instances of SendPort, and lists and maps whose elements are any of these. List and maps are also allowed to be cyclic." – cs guy Oct 14 '20 at 21:08
  • 1
    they/re right: you need to call `SendPort.send()` method each time you want to update your ui with the current progress - but i forgot you can use `IsolateChannel` too - that way you work with "normal" `Stream` protocol interface: you have `stream` and `sink` properties – pskink Oct 15 '20 at 05:08
  • 1
    so with `IsolateChannel` ui uses `channel.stream.listen` and isolate uses `channel.sink.add` – pskink Oct 15 '20 at 10:11
  • 1
    i have solved my problem by passing SendPorts inside a map at initial function call, i removed function passing which was causing the error, its a bit hacky but the code is clear and no 3rd party libs, thank you for the suggestion :) – cs guy Oct 15 '20 at 10:55
  • 1
    yep, it is a hard, hacky way, better check `IsolateChannel` - it really pays off – pskink Oct 15 '20 at 15:36

1 Answers1

4

I had the same problem, the solution is to not pass any function nor an object that has a function as property. Then it should work.

Corentin Houdayer
  • 988
  • 2
  • 8
  • 19