Search code examples
flutterdartdart-isolates

Flutter - ReceiverPort doesn't listen data


I'm using flutter_downloader package and I have to get the data in listen method, but it doesn't work. I don't receive anything. I read that the issue could be because in send method I have to paste only primitive objects and I've changed it, but it still doesn't work

  final ReceivePort _receivePort = ReceivePort();
  int? status;
  int? progress;
  String? id;

  @override
  void initState() {
    IsolateNameServer.registerPortWithName(_receivePort.sendPort, 'downloader_send_port');
    _receivePort.listen(
      (data) async {
        Logger().e('task listen data: $data'); //doesn't work here
        // setState(() {
        //   id = data[0];
        //   status = data[1];
        //   progress = data[2];
        // });
      },
    );
    FlutterDownloader.registerCallback(downloadCallback);
    super.initState();
  }

  @override
  void dispose() {
    IsolateNameServer.removePortNameMapping('downloader_send_port');
  }

  @pragma('vm:entry-point')
  static void downloadCallback(String id, DownloadTaskStatus status, int progress) {
    final SendPort? send = IsolateNameServer.lookupPortByName('downloader_send_port');
    Logger().e('task send id: $id');
    Logger().e('task send status: ${status.value}');
    Logger().e('task send progress: $progress');
    send?.send([id, status.value, progress]);
  }

in logs I have only data from callback method but nothing from listening

flutter: \^[[38;5;196m│ ⛔ task send id: io.myair.download.task.73570.1683533984.371354<…>
flutter: \^[[38;5;196m│ ⛔ task send status: 1<…>
flutter: \^[[38;5;196m│ ⛔ task send progress: 0<…>
flutter: \^[[38;5;196m│ ⛔ task send id: io.myair.download.task.73570.1683533984.371354<…>
flutter: \^[[38;5;196m│ ⛔ task send status: 3<…>
flutter: \^[[38;5;196m│ ⛔ task send progress: 100<…>

Solution

  • I'm not sure where is the difference, but it works if write it as in example from package https://github.com/fluttercommunity/flutter_downloader/blob/master/example/lib/home_page.dart

    final ReceivePort _receivePort = ReceivePort();
      DownloadTaskStatus? status;
      int? progress;
      String? id;
    
      @pragma('vm:entry-point')
      static void downloadCallback(
        String id,
        DownloadTaskStatus status,
        int progress,
      ) {
        print(
          'Callback on background isolate: '
          'task ($id) is in status ($status) and process ($progress)',
        );
    
        IsolateNameServer.lookupPortByName('downloader_send_port')?.send([id, status.value, progress]);
      }
    
      void _unbindBackgroundIsolate() {
        IsolateNameServer.removePortNameMapping('downloader_send_port');
      }
    
      void _bindBackgroundIsolate() {
        final isSuccess = IsolateNameServer.registerPortWithName(
          _receivePort.sendPort,
          'downloader_send_port',
        );
        if (!isSuccess) {
          _unbindBackgroundIsolate();
          _bindBackgroundIsolate();
          return;
        }
        _receivePort.listen((dynamic data) {
          final taskId = (data as List<dynamic>)[0] as String;
          final status = DownloadTaskStatus(data[1] as int);
          final progress = data[2] as int;
    
          print(
            'Callback on UI isolate: '
            'task ($taskId) is in status ($status) and process ($progress)',
          );
    
          setState(() {
            id = taskId;
            this.status = status;
            this.progress = progress;
          });
        });
      }
    
      @override
      void initState() {
        _bindBackgroundIsolate();
        FlutterDownloader.registerCallback(downloadCallback, step: 1);
        super.initState();
      }
    
      @override
      void dispose() {
        _unbindBackgroundIsolate();
        super.dispose();
      }