Flutter中ReceivePort无法监听flutter_downloader下载进度问题
FlutterDownloader ReceivePort无法监听下载进度的排查与解决
问题分析
你的downloadCallback能正常打印日志,但ReceivePort的监听回调无输出,说明下载回调已触发,但跨Isolate的端口通信出现异常,大概率是SendPort获取失败或数据序列化问题导致的。
排查与解决步骤
先确认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,说明端口注册失败或未找到,继续下一步排查。确保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(); }
- 在
规避枚举跨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'); });检查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
相关产品推荐
相关产品推荐

