关于flutter:剖析flutterdownloadmanager学习如何做下载管理暂停和取消

28次阅读

共计 3431 个字符,预计需要花费 9 分钟才能阅读完成。

前言

内容类利用中图片或文件下载,个别利用中利用更新和降级,这些都是经典的下载场景。下载是我的项目中根底且重要的模块。

从代码逻辑复用性和人力老本思考,始终想实现一个纯 Dart 实现的下载库,作为技术储备。

最近发现了一个纯 Dart 实现的下载库 flutter_download_manager, 相对来说各方面还算满足需要,反对断点续传,暂停,勾销等我比拟看重的性能。然而有些中央还须要改良。

话不多说,首先简略介绍下这个库吧。

flutter_download_manager 简介

地址:https://github.com/nabil6391/flutter_download_manager

版本:0.5.4

特点:

  • 纯 Dart 实现
  • 通过 url 治理下载工作
  • 可能告诉状态和进度更改
  • 局部下载性能
  • 队列下载
  • 暂停、勾销或复原下载
  • 并行文件下载(2 个或能够更改)
  • 反对批量下载

反对平台:Linux | MacOS | Windows | Android | iOS

应用办法

简略下载一个文件

var dl = DownloadManager();
var url = "adasdad.com/asda.sdas";
dl.addDownload(url, "./test.sdas");

DownloadTask? task = dl.getDownload(url4);

task?.status.addListener(() {print(task.status.value);
});

task?.progress.addListener(() {print(task.progress.value);
});

await dl.whenDownloadComplete(url4);

获取下载状态

DownloadTask? task = dl.getDownload(url4);
task?.status.addListener(() {print(task.status.value);
});

获取下载进度

DownloadTask? task = dl.getDownload(url4);
task?.progress.addListener(() {print(task.progress.value);
});

期待工作实现

DownloadTask? task = dl.getDownload(url4);
await task.whenDownloadComplete();

勾销下载工作

var dl = DownloadManager();
dl.cancelDownload(url5);

暂停下载工作

var dl = DownloadManager();
dl.pauseDownload(url5);

复原下载工作

var dl = DownloadManager();
dl.resumeDownload(url5);

成果展现

源码解析

类图

工作治理类:DownloadManager

整个外围就类 DownloadManager, 而每个下载工作的形象是 DownloadTask,所谓 Manager 当然是要治理这些 Task 了。那么如何治理呢?游离的没法管控,只有先找到能力调配,通过 Map 持有 Task 句柄达到“找到”目标,其中_cache 中以 < 下载 URL, 下载工作 > 形式在内存中缓存每个工作状态;而_queue 则是新增加的下载工作申请,这两者关系前面流程中会具体讲到。

工作的形象:DownloadTask

重点说下 status 和 progress 字段设计,不论是批量下载还是单任务下载,进度监听不是通过传统传入一个回调给 download 或者 addDownload 来进行的,而是用了零碎的 ValueNotifier。笔者思考这样设计起因是配合 flutter 零碎提供的 ValueListenerBuilder 更容易组织 UI。(这样的设计是不是看起来更 Dart)

工作申请形象:DownloadRequest

重点说下 cancelToken,该字段在暂停,勾销,复原下载工作实现中起了关键作用。像放出去的风筝,想发出时能够发出。怎么发出呢?通过线,这条线的作用就是 cancelToken。而风筝就像是一个个工作申请,放风筝的人就是 Manager,放风筝这件事就是 Task。

每个申请都必须带个 cancelToken,不便勾销申请。(不带线的风筝,难道让你入地?)

未标明办法阐明

图中 DownloadManager 中办法只写了单任务下载相干办法,批量相干办法差不多就省略了,相似 (add | pause | cancel | resume | remove).BatchDownload 等,最终通过循环执行了单实现的办法。

原理解析

如何治理工作

这里不具体论述代码流程,为不便了解间接拿生存中习用做事逻辑举例,代码实现可自行查阅,也是依照这个套路来滴,首先有两个汇合:

  • 工作申请列表,外面是想做的事件,每件事件如果非要定义状态的话,能够说是“布局中”。

后续简称工作列表均指申请列表。

  • 工作治理表,外面的事件个别不会去记,在脑子外面。软件开发中,PM 该表格维护者。

实现某工作个别流程如下:

  1. 生成一个工作申请表白志愿。
  2. 查问工作治理表中工作状态并决定是否有资格真正增加到申请列表。
  3. 已实现工作 :3 天前曾经摸过了一次鱼,一周最多摸鱼一次,间接返回工作后果,否掉这种不切实际的想法,没脸退出申请列表。
  4. 未开始工作 :一周没玩 lol,能够将游戏增加到申请列表中,并更新到工作治理列表中。
  5. 未执行完工作 :搬砖上次搬了 50% 下周持续搬。此时看你怎么解决了,若 50% 的砖还在,你能够持续搬,将工作增加到申请列表,从 50% 开始直到实现。若没搬的砖堆得横七竖八不想持续码,可删除工作治理表中记录,当一次新工作增加申请列表和治理列表中。
  6. 新布局工作 :工作治理列表中无该记录的状况,当新工作从新增加到申请列表中。
  7. 循环执行申请列表中各工作并适时更新治理列表中状态,直至申请列表为空。

流程图如下:

如何实现暂停复原勾销

要害是对 DownloadRequest 中 cancelToken 的管制。

暂停工作

复原工作

勾销工作

暂停和勾销工作骗谁呢?

个别了解暂停示意之前下载了 50%,复原后持续从 50% 下载;勾销示意之前下载 50% 点击复原重头再来。

暂停和勾销逻辑除更新状态不一样其余根本一样,是在忽悠我么?

莫慌!在下载时候还有解决呢?

通过上述复原实现与如下下载中逻辑演绎整个暂停实现流程:

  1. 复原下载中③④⑤会赋予暂停中 url 新的 CancelToken 从新增加到申请列表中,并开启申请列表的自遍历执行。
  2. 申请列表的自遍历执行是给暂停掉 Task 从新执行的机会,Cancel 掉的工作就没法再执行了 (下述第 6 行)。
  3. 下载过程中如果之前暂停未下载结束的文件,通过设置 header 中 range:bytes 来实现断点续传(下述第 29 行)。

长处和毛病

长处

  • 逻辑复用:Dart 侧反对暂停,勾销,复原,下载流程,个别下载框架会用桥接实现,波及到多端实现和通用性问题,比拟耗人力。要么就是 dio 简略实现下载,没有暂停复原等实现。
  • 工作治理,个别利用都是单任务下载,没有治理过程。
  • 代码简单明了可读性强,类形象正当合乎繁多职责。

毛病

  • 工作治理列表只实现了内存缓存未实现磁盘缓存, 利用退出再进入啥都没了。
  • 网络库不反对扩大,太过依赖 dio。

预报:下一篇将实现 dio 解耦和网络库扩大。

import 'package:dio/dio.dart';

class DownloadRequest {var cancelToken = CancelToken();
 }

------------------------------------------------
import 'package:dio/dio.dart';
class DownloadManager {var dio = Dio();

Future<void> download(String url, String savePath, cancelToken,
      {forceDownload = false}) async {
//...
if(fileExist){}else(partialFileExist)
{var response = await dio.download(...);
}else{var response = await dio.download(...);
}

总结

工作治理体现在列表的增删改查; 断点续传体现在 range 设置; 工作勾销单纯通过申请库勾销实现。

❤️本文由 编程黑板报 原创,欢送关注同名公众号,原创技术文章第一工夫推送。❤️

正文完
 0