背景
最近有涉及到下載相關(guān)的業(yè)務(wù)舱污,所以去研究了下Flutter社區(qū)的下載工具庫谋右,pub.dev經(jīng)過fluttercommunity.dev認(rèn)證的下載庫是flutter_downloader
flutter_downloader提供了下載的一些基礎(chǔ)功能宫屠。例如任務(wù)id映射谅畅、任務(wù)隊(duì)列胚迫、線程隔離贾铝、原生交互
值得一提的是flutter_downloader官方提供的示例教程flutter_downloader/example
這套教程你寫了一大段具體業(yè)務(wù)薯定,主要邏輯是taskId維護(hù)始绍、disk/memory緩存同步;個(gè)人認(rèn)為flutter_downloader從易用性角度來說設(shè)計(jì)的不是很友好话侄,沒有達(dá)到開箱即用的效果亏推,例如其中的2個(gè)問題:
標(biāo)識(shí)下載任務(wù)的唯一id(taskId)可能在一次pause/resume后變掉了?那怎么進(jìn)行任務(wù)管理满葛?
下載回調(diào)方法里沒有url信息径簿,但是flutter_downloader本地?cái)?shù)據(jù)庫卻有,如果想手動(dòng)綁定taskId和url嘀韧,難道我要在每一次下載任務(wù)回調(diào)i/o本地?cái)?shù)據(jù)庫篇亭?
為了解決這些問題,便利地把flutter_downloader投入業(yè)務(wù)锄贷,最好進(jìn)行二次封裝译蒂。
二次封裝后能夠做到:
跟蹤taskId和url的映射關(guān)系,調(diào)用方通過url管理下載任務(wù)谊却,而不是taskId
-
外界弱化對(duì)flutter_downloader所維護(hù)的下載狀態(tài)的感知柔昼;flutter_downloader維護(hù)了
7
種下載狀態(tài),其實(shí)可以完全為調(diào)用方屏蔽掉例如undefined炎辨、enqueued這些狀態(tài)
image.png 在盡量少的I/O前提下捕透,進(jìn)行disk/memory緩存同步
提供便利的下載句柄
提供批量下載接口(因flutter_downloader未提供具體下載字節(jié)數(shù),目前批量進(jìn)度 = 已下載任務(wù)個(gè)數(shù)/總?cè)蝿?wù)個(gè)數(shù))
為了解決上述的一些問題碴萧,基于flutter_downloader乙嘀,自維護(hù)了一個(gè)下載器al_downloader,目前已經(jīng)投入到了我們這邊業(yè)務(wù)中使用了破喻,如有不足虎谢,希望大家?guī)兔χ刚齸
al_downloader
一個(gè)基于url的Flutter下載器,支持下載任意類型的文件曹质,并自動(dòng)管理下載相關(guān)的各種事務(wù)婴噩。
特性
- 通過url管理下載任務(wù)
- 簡(jiǎn)單的下載狀態(tài)
- 不頻繁地I/O
- 提供便利的下載句柄
- 支持批量下載
- 自動(dòng)管理文件擎场,不需要指定下載路徑
- 基于flutter_downloader
集成
原生配置:和flutter_downloader相同
添加下面這行代碼到pubspec.yaml中
dependencies:
al_downloader: ^1.8.2
使用命令行運(yùn)行下面這行代碼
flutter packages get
引入下面這行代碼來使用al_downloader
import 'package:al_downloader/al_downloader.dart';
使用
ALDownloader
初始化
ALDownloader.initialize();
配置打印
ALDownloader.configurePrint(true, frequentEnabled: false);
下載
ALDownloader.download(url,
directoryPath: directoryPath,
fileName: fileName,
handlerInterface:
ALDownloaderHandlerInterface(progressHandler: (progress) {
debugPrint(
'ALDownloader | 下載進(jìn)度 = $progress, url = $url\n');
}, succeededHandler: () {
debugPrint('ALDownloader | 下載成功, url = $url\n');
}, failedHandler: () {
debugPrint('ALDownloader | 下載失敗, url = $url\n');
}, pausedHandler: () {
debugPrint('ALDownloader | 下載暫停, url = $url\n');
}));
添加一個(gè)下載句柄池
ALDownloader.addHandlerInterface(
ALDownloaderHandlerInterface(progressHandler: (progress) {
debugPrint(
'ALDownloader | 下載進(jìn)度 = $progress, url = $url\n');
}, succeededHandler: () {
debugPrint('ALDownloader | 下載成功, url = $url\n');
}, failedHandler: () {
debugPrint('ALDownloader | 下載失敗, url = $url\n');
}, pausedHandler: () {
debugPrint('ALDownloader | 下載暫停, url = $url\n');
}),
url);
添加一個(gè)持久下載句柄池
ALDownloader.addForeverHandlerInterface(
ALDownloaderHandlerInterface(progressHandler: (progress) {
debugPrint(
'ALDownloader | 下載進(jìn)度 = $progress, url = $url\n');
}, succeededHandler: () {
debugPrint('ALDownloader | 下載成功, url = $url\n');
}, failedHandler: () {
debugPrint('ALDownloader | 下載失敗, url = $url\n');
}, pausedHandler: () {
debugPrint('ALDownloader | 下載暫停, url = $url\n');
}),
url);
移除下載句柄池
ALDownloader.removeHandlerInterfaceForUrl(url);
暫停下載
/// 停止下載,不刪除未下載完成的數(shù)據(jù)
ALDownloader.pause(url);
取消下載
/// 停止下載几莽,刪除未下載完成的數(shù)據(jù)
ALDownloader.cancel(url);
移除下載
/// 刪除下載迅办,刪除所有數(shù)據(jù)
ALDownloader.remove(url);
獲取下載狀態(tài)
final status = await ALDownloader.getStatusForUrl(url);
獲取下載進(jìn)度
final progress = await ALDownloader.getProgressForUrl(url);
獲取任務(wù)
final task = await ALDownloader.getTaskForUrl(url);
獲取全部任務(wù)
final tasks = await ALDownloader.tasks;
ALDownloaderBatcher
批量下載
ALDownloaderBatcher.download(urls,
handlerInterface:
ALDownloaderHandlerInterface(progressHandler: (progress) {
debugPrint('ALDownloader | 批量 | 下載進(jìn)度 = $progress\n');
}, succeededHandler: () {
debugPrint('ALDownloader | 批量 | 下載成功\n');
}, failedHandler: () {
debugPrint('ALDownloader | 批量 | 下載失敗\n');
}, pausedHandler: () {
debugPrint('ALDownloader | 批量 | 下載暫停\n');
}));
對(duì)批量下載添加一個(gè)下載句柄池
ALDownloaderBatcher.addHandlerInterface(
ALDownloaderHandlerInterface(progressHandler: (progress) {
debugPrint('ALDownloader | 批量 | 下載進(jìn)度 = $progress\n');
}, succeededHandler: () {
debugPrint('ALDownloader | 批量 | 下載成功\n');
}, failedHandler: () {
debugPrint('ALDownloader | 批量 | 下載失敗\n');
}, pausedHandler: () {
debugPrint('ALDownloader | 批量 | 下載暫停\n');
}),
urls);
獲取一組url的下載狀態(tài)
final status = ALDownloaderBatcher.getStatusForUrls(urls);
獲取一組任務(wù)
final tasks = await ALDownloaderBatcher.getTasksForUrls(urls);
ALDownloaderFileManager - 基于url的文件管理器
final physicalFilePath =
await ALDownloaderFileManager.getPhysicalFilePathForUrl(url);
debugPrint(
'ALDownloader | 獲取[url]的物理文件路徑, url = $url, path = $physicalFilePath\n');
提示:
1. 如果持久化文件被一些異常方式刪除了,比如某些業(yè)務(wù)代碼刪除了緩存文件夾章蚣,調(diào)用[remove]礼饱,然后調(diào)用[download]重新下載來解決這個(gè)問題
Example的主要文件
iOS
Android
貢獻(xiàn)
歡迎貢獻(xiàn)!
如果你有任何問題究驴、建議或想法,歡迎隨時(shí)提出issue或PR匀伏!
Maintainer: jackleemeta (jackleemeta@outlook.com)