Flutter 下载篇 - 贰 | 当下载器遇上切换网络库
需求背景
继上篇《Flutter 下载篇 - 壹 | flutter_download_manager 源码解析》中详细介绍了 flutter_download_manager 用法和原理。在优缺点中提到,该库纯 Dart 实现,支持下载管理,暂停,恢复,取消和断点续传。其中有个缺点是网络库与 dio 强耦合,不支持自定义网络库扩展。
有人会说: dio 这么牛逼,直接用不就好了,为啥还要支持别的网络库,没事别瞎折腾。
我想说:
- 世界不只有一种声音,那不然多无趣。
- 第三方库对应用本身来说是黑盒,开发者一般疏于关注其功能改动对应用影响除非产生重大事故,这种不可控的情况应谨慎。
- 设计上遵循 DIP 原则,抽象不要依赖具体实现细节,具体细节依赖抽象,我们需要抽象网络层来给项目依赖而非直接依赖 dio。
- 快速切换到其他网路库。
本文将从现状出发,一步步带你解耦 flutter_download_manager 中的网络库。
现状说明
从类图上整体了解 flutter_download_manager 类设计过程中对 dio 强耦合概括,然后通过代码具体讲解。
类图体现

代码体现
耦合点一:dio.CancelToken

每个下载任务请求中都会使用到 dio:CancelToken 通过 dio 网络库间接实现任务的取消功能。
耦合点二:dio.download
cancelToken.cancel() 算依赖 CancelToken

如上简写代码中调用链关系,最终调用链及对 dio 依赖关系总结:
下载库对 dio 的依赖在于: CancelToken 和 download 方法。

如何定制网络库
通过上述对现状分析总结,结合设计基本原则:封装变化将不变从变化中隔离出来。其中变化的就是网络库的下载,CancelToken 和取消功能。只用封装这部分变化,将网络库下载和 Token 抽象出来进行封装。
1. 网络层设计
目的:让 flutter_download_manager 与 dio.download 解耦。
思路:将网络相关操作抽象成接口,依赖注入到 downloadManager 对象中。
实施步骤:
- 抽象网络层接口
考虑到 download 返回 Future 中对象问题,因为会用到 response.statusCode,这里直接用 dynamic 来,具体可以细化成封装成 DownloadResponse,其中包含 statusCode 属性。

- customhttpclient 通过依赖注入传入 DownloadManager,让其不依赖具体实现而依赖抽象,依赖注入实现对象之间的组合关系提高扩展性。

2. CancelToken 设计
目的:让 flutter_download_manager 与 dio.CancelToken 解耦。
思路:CancelToken 与取消息息相关,而且必须提供一个 cancel 方法来供 downloadmanager 中暂停等方法使用。考虑到每个 custom_http_client 的 CancelToken 结构体存在不一样,而 cancel 方法命名多样性原则,这里设计一个统一的 DownloadCancelToken 接口,提供 cancel 方法,将其中实现代理给具体网络库的 CancelToken 对象。
实施步骤:
- 抽象一个 Token 对象并提供 cancel 方法,并实现一个默认代理其他网络库的 Proxy 类。
小技巧: 用 Function.apply 是因为它本身支持位置参数和可选参数传入。

- custom_http_client 中抽象一个 DownloadCancelToken 抽象接口供外部使用

3. 下载器设计
目的:下载器与具体实现 downloadmanager 解耦
思路:downloadmanager 中提供了 addDownload 等下载通用方法及下载管理逻辑抽象。这块存在变化可以有多种实现,也抽象下。
实施步骤:
- 下载器抽象成接口

- downloadManager 依赖 IDownloader

至此,可定制网络库改造已全部完成,接下来就可以隔离 dio 网络实现了。
网络库隔离效果

通过依赖注入到 DownloadManager 中即可。

如此就完成了对 flutter_download_manager 的网络库扩展改造,实现了一个可定制化的网络框架的下载库。
总结
做开闭原则前,最重要的是以最小实现模型为基础捋清楚代码中的变与不变。
太棒了!鼓励自己坚持到底。我希望我为你投入的时间增加了一些价值。
如果觉得文章对你有帮助,点赞、收藏、关注、评论,一键四连支持,你的支持就是我创作最大的动力。
️ 本文由 听蝉 原创,欢迎关注公众号:编程黑板报 原创技术文章第一时间推送。 ️
Flutter 下载篇 - 贰 | 当下载器遇上切换网络库的更多相关文章
- iOS开发网络篇—多线程断点下载
iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...
- 微端游戏启动器launcher的制作之下载篇(系列一)
首先第一篇先讲一讲launcher最核心的功能---下载功能. 这个部分估计得好几篇才能写完,东西比较多也比较杂,慢慢来吧,我的东西也在继续改进中...... 从web上下载文件需要用到几个类,Htt ...
- ios开发视频播放后台下载功能实现 :1,ios播放视频 ,包含基于AVPlayer播放器,2,实现下载,iOS后台下载(多任务同时下载,单任务下载,下载进度,下载百分比,文件大小,下载状态)(真机调试功能正常)
ABBPlayerKit ios开发视频播放后台下载功能实现 : 代码下载地址:https://github.com/niexiaobo/ABBPlayerKit github资料学习和下载地址:ht ...
- spring boot编程思想(核心篇) pdf 下载 it教程
资料简介:本书是<Spring Boot 编程思想>的核心篇,开篇总览Spring Boot核心特性,接着讨论自动装配(Auto-Configuration)与SpringApplicat ...
- SpringMVC的文件上传下载,异常处理,拦截器的小总结
文件的上传和下载 我们通常在访问网页时会使用到文件的上传与下载的功能,那么他是如何实现的呢? 1 下载: ResponseEntity :用于控制器方法的返回值类型,该控制器方法的返回值就是响应到浏览 ...
- Java实现FTP批量大文件上传下载篇1
本文介绍了在Java中,如何使用Java现有的可用的库来编写FTP客户端代码,并开发成Applet控件,做成基于Web的批量.大文件的上传下载控件.文章在比较了一系列FTP客户库的基础上,就其中一个比 ...
- (数据科学学习手札114)Python+Dash快速web应用开发——上传下载篇
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- 人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载
人工智能大数据,公开的海量数据集下载,ImageNet数据集下载,数据挖掘机器学习数据集下载 ImageNet挑战赛中超越人类的计算机视觉系统微软亚洲研究院视觉计算组基于深度卷积神经网络(CNN)的计 ...
- 视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频
视频下载四大神器—如何下载优酷/爱奇艺/腾讯/B站超清无水印视频 2018-07-11 | 标签»下载, 下载工具, 视频 又是视频下载,老生常谈的话题.阿刚同学已在乐软博客多次与大家分享推荐 ...
- 【浅墨Unity3D Shader编程】之三 光之城堡篇:子着色器、通道与标签的写法 & 纹理混合
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1117/120.html 作者:毛星云 ...
随机推荐
- from表单前后端数据编码格式-Ajax发送json格式数据-Ajax发送文件-Django自带序列化组件-Ajax结合sweetalert
目录 一:前后端传输数据的编码格式(contentType) 1.研究post请求数据的编码格式 2.可以朝后端发送post请求的方式 3.前后端传输数据的编码格式 4.研究form表单 5.当for ...
- 记一次 .NET 某工控MES程序 崩溃分析
一:背景 1.讲故事 前几天有位朋友找到我,说他的程序出现了偶发性崩溃,已经抓到了dump文件,Windows事件日志显示的崩溃点在 clr.dll 中,让我帮忙看下是怎么回事,那到底怎么回事呢? 上 ...
- SQLMap入门——获取当前网站数据库的用户名称
列出当前网站使用的数据库用户 python sqlmap.py -u http://localhost/sqli-labs-master/Less-1/?id=1 --current-user
- 5、枚举Enum
枚举类会隐式的继承Enum类,无法再继承其它类(单继承机制) 一.无实参枚举类型: 1.定义: /** * 1.无实参枚举类型 */ public enum NoParamTypeEnums { SP ...
- 1_使用swiper数组对象循环图片遇到的问题
今天在练习微信小程序的swiper组件时,想用列表循环出图片,发现图片一直没出来,控制台也没有报错,后来仔细一看,原来是语法格式写错了. 以下是我列表循环踩过的坑: 一:微信小程序的列表循环和vue的 ...
- cookie、session,、token,还在傻傻分不清?
摘要:session 和 token 本质上是没有区别的,都是对用户身份的认证机制,只是他们实现的校验机制不一样而已. 本文分享自华为云社区<Session/Cookie/Token 还傻傻分不 ...
- 用python爬取网络文章----滴天髓
用python爬取网络文章真的很简单.主要分以下几个步骤 1.安装并导入相关模块. 这里我们要用到两个模块,分别是reqesets和lxml 安装命令pip install requests和pip ...
- P8865 [NOIP2022] 种花
简要题意 \(T\) 组数据,给你一个 \(n\times m\) 的 \(01\) 矩阵. \(0\) 部分可以组成 \(A_c\) 个 \(\texttt{C}\) 型图案和 \(A_f\) 个 ...
- 闻其声而知雅意,基于Pytorch(mps/cpu/cuda)的人工智能AI本地语音识别库Whisper(Python3.10)
前文回溯,之前一篇:含辞未吐,声若幽兰,史上最强免费人工智能AI语音合成TTS服务微软Azure(Python3.10接入),利用AI技术将文本合成语音,现在反过来,利用开源库Whisper再将语音转 ...
- DOM的操作(增删改查)
操作DOM的核心就是增删改查 目录 一.节点创建型API 1.1 createElement 1.2 createTextNode 1.3 cloneNode 1.4 createDocumentFr ...