美文网首页
flutter_downloader下载完成后获取下载任务失败问

flutter_downloader下载完成后获取下载任务失败问

作者: 黑炭长 | 来源:发表于2023-03-29 15:38 被阅读0次

    flutter_downloader 我们用来下载照片,需求是下载后要保存到相册 在下载进度回调中需要获取相关的任务 拿到下载图片的路径,即可保存资源到相册
    问题代码:

    
    initDownLoad() async {
        if (!FlutterDownloader.initialized) {
          await FlutterDownloader.initialize(
              debug: BaseConfig.isDebug, ignoreSsl: true);
        }
    
        if (!_isInitialized) {
          await FlutterDownloader.registerCallback(downloadCallback);
        }
        _isInitialized = true;
      }
    @pragma('vm:entry-point')
      static void downloadCallback(
          String id, DownloadTaskStatus status, int progress) async {
    if (status.value == DownloadTaskStatus.complete.value &&
                progress == 100) {
        final list = await FlutterDownloader.loadTasksWithRawQuery(
              query: 'SELECT * FROM task WHERE task_id = \"$id\"');
          if (list != null && list.isNotEmpty) {
            return list.first.savedDir + '/' + (list.first.filename ?? '');
          }
    }
      }
    

    下载完成后 使用FlutterDownloader.loadTasksWithRawQuery获取相应的下载任务,来获取下载资源路径,但是明明已经初始化了下载器,但是调用该方法会触发assert(_initialized, 'plugin flutter_downloader is not initialized');
    在该回调方法外部调用FlutterDownloader.loadTasksWithRawQuery就么有该问题,没找到具体的原因

    解决:
    看插件介绍是在回调方法中使用IsolateNameServer,同步下载进度,进行更改,代码为

    @pragma('vm:entry-point')
      static void downloadCallback(
          String id, DownloadTaskStatus status, int progress) async {
        final SendPort? send =
            IsolateNameServer.lookupPortByName('downloader_send_port');
        send?.send([id, status.value, progress]);
      }
    
      initDownLoad() async {
        if (!FlutterDownloader.initialized) {
          await FlutterDownloader.initialize(
              debug: BaseConfig.isDebug, ignoreSsl: true);
        }
    
        if (!_isInitialized) {
          IsolateNameServer.registerPortWithName(
              _port.sendPort, 'downloader_send_port');
          _port.listen((dynamic data) async {
            String id = data[0];
            DownloadTaskStatus status = DownloadTaskStatus(data[1]);
            int progress = data[2];
    
            sysDownloadProgress(id, progress, status.value);
            if (status.value == DownloadTaskStatus.complete.value &&
                progress == 100) {
              print('=========status: ${status.value}');
    
              String path = await AlbumDownloadManager().handleOriginPath(id);
              if (path.length > 0) {
                studySaveImage(bytesList: File(path).readAsBytesSync());
              }
            }
          });
    
          await FlutterDownloader.registerCallback(downloadCallback);
        }
        _isInitialized = true;
      }
    

    更改后竟可以获取路径了,网上相关的资料比较少,在这里记录一下,有遇到相关问题的,同时找到原因的,希望不吝赐教

    补充:

    原因其实在callback方法的说明中已经给出
    Your UI is rendered on the main isolate, while download events come from a
    background isolate (in other words, code in [callback] is run in the
    background isolate), so you have to handle the communication between two
    isolates.
    意思是下载进度和UI刷新分属于两个不同的isolates,两个isolates的内存是不共享的,所以出现了开始的 在下载回调中获取任务提示下载器没有初始化,我们需要处理两个isolates的通信,所以修改后问题解决,具体的可参考这两篇文章
    isolates
    FlutterEngine
    欢迎评论 + 私信

    相关文章

      网友评论

          本文标题:flutter_downloader下载完成后获取下载任务失败问

          本文链接:https://www.haomeiwen.com/subject/cnpfddtx.html