You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中ReceivePort无法监听flutter_downloader下载进度问题

FlutterDownloader ReceivePort无法监听下载进度的排查与解决

问题分析

你的downloadCallback能正常打印日志,但ReceivePort的监听回调无输出,说明下载回调已触发,但跨Isolate的端口通信出现异常,大概率是SendPort获取失败或数据序列化问题导致的。

排查与解决步骤

  1. 先确认SendPort是否成功获取
    在downloadCallback中添加日志,检查端口查找结果:

    @pragma('vm:entry-point')
    static void downloadCallback(
        String id, DownloadTaskStatus status, int progress) {
      log("downloadCallback => $id, $status, $progress");
      final SendPort? send = IsolateNameServer.lookupPortByName('downloader_sendport');
      // 新增日志,检查send是否为空
      log('SendPort lookup result: $send');
      send?.send([id, status.value, progress]);
    }
    

    如果日志显示send为null,说明端口注册失败或未找到,继续下一步排查。

  2. 确保ReceivePort正确注册与销毁

    • 在initState注册端口后,立即验证注册状态:
      @override
      void initState() {
        super.initState();
        IsolateNameServer.registerPortWithName(port.sendPort, 'downloader_sendport');
        // 验证端口是否注册成功
        final registeredPort = IsolateNameServer.lookupPortByName('downloader_sendport');
        log('Registered port: $registeredPort');
        port.listen((dynamic data) {
          log('data: $data');
        });
        FlutterDownloader.registerCallback(downloadCallback);
      }
      
    • 页面销毁时必须注销端口,避免端口残留导致后续查找错误:
      @override
      void dispose() {
        IsolateNameServer.removePortNameMapping('downloader_sendport');
        port.close();
        super.dispose();
      }
      
  3. 规避枚举跨Isolate序列化异常
    DownloadTaskStatus是枚举类型,跨Isolate传递时可能存在序列化问题,建议转为int值传递,再在监听回调中转换回来:

    // 回调中发送数据
    send?.send([id, status.value, progress]);
    
    // 监听回调中解析数据
    port.listen((dynamic data) {
      String taskId = data[0];
      DownloadTaskStatus taskStatus = DownloadTaskStatus.values[data[1]];
      int taskProgress = data[2];
      log('Received download data: $taskId, $taskStatus, $taskProgress');
    });
    
  4. 检查Android平台配置(若适用)
    如果是Android平台,确认AndroidManifest.xml中已配置flutter_downloader所需权限与服务(下载功能正常则大概率已配置,可再核对):

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    <application ...>
      <provider
          android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
          android:authorities="${applicationId}.flutter_downloader.provider"
          android:exported="false"
          android:grantUriPermissions="true">
          <meta-data
              android:name="android.support.FILE_PROVIDER_PATHS"
              android:resource="@xml/provider_paths"/>
      </provider>
    </application>
    

总结

最常见的问题是端口未正确注册/注销或枚举序列化异常,按照上述步骤逐一排查,基本可以解决ReceivePort无法监听的问题。

内容的提问来源于stack exchange,提问作者MedCh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:45:50