美文网首页Flutter
Flutter 下载器 al_downloader

Flutter 下载器 al_downloader

作者: mtko | 来源:发表于2021-09-01 12:34 被阅读0次

    先上下载器链接

    背景

    最近有涉及到下载相关的业务,所以去研究了下Flutter社区的下载工具库,pub.dev经过fluttercommunity.dev认证的下载库是flutter_downloader

    flutter_downloader提供了下载的一些基础功能。例如任务id映射、任务队列、线程隔离、原生交互

    值得一提的是flutter_downloader官方提供的示例教程flutter_downloader/example

    这套教程你写了一大段具体业务,主要逻辑是taskId维护、disk/memory缓存同步;个人认为flutter_downloader从易用性角度来说设计的不是很友好,没有达到开箱即用的效果,例如其中的2个问题:

    • 标识下载任务的唯一id(taskId)可能在一次pause/resume后变掉了?那怎么进行任务管理?

    • 下载回调方法里没有url信息,但是flutter_downloader本地数据库却有,如果想手动绑定taskId和url,难道我要在每一次下载任务回调i/o本地数据库?

    为了解决这些问题,便利地把flutter_downloader投入业务,最好进行二次封装。

    二次封装后能够做到:

    • 跟踪taskId和url的映射关系,调用方通过url管理下载任务,而不是taskId

    • 外界弱化对flutter_downloader所维护的下载状态的感知;flutter_downloader维护了7种下载状态,其实可以完全为调用方屏蔽掉例如undefined、enqueued这些状态

      image.png
    • 在尽量少的I/O前提下,进行disk/memory缓存同步

    • 提供便利的下载句柄

    • 提供批量下载接口(因flutter_downloader未提供具体下载字节数,目前批量进度 = 已下载任务个数/总任务个数)

    为了解决上述的一些问题,基于flutter_downloader,自维护了一个下载器al_downloader,目前已经投入到了我们这边业务中使用了,如有不足,希望大家帮忙指正~

    al_downloader

    一个基于url的Flutter下载器,支持下载任意类型的文件,并自动管理下载相关的各种事务。

    特性

    • 通过url管理下载任务
    • 简单的下载状态
    • 不频繁地I/O
    • 提供便利的下载句柄
    • 支持批量下载
    • 自动管理文件,不需要指定下载路径
    • 基于flutter_downloader

    集成

    原生配置:和flutter_downloader相同

    添加下面这行代码到pubspec.yaml中

    dependencies:
      al_downloader: ^1.5.9
    

    使用命令行运行下面这行代码

    flutter packages get
    

    引入下面这行代码来使用al_downloader

    import 'package:al_downloader/al_downloader.dart';
    

    使用

    ALDownloader

    /// 下载
    await ALDownloader.download(url,
        downloaderHandlerInterface:
            ALDownloaderHandlerInterface(progressHandler: (progress) {
          debugPrint(
              "ALDownloader | 下载进度 = $progress, url = $url\n");
        }, succeededHandler: () {
          debugPrint("ALDownloader | 下载成功, url = $url\n");
        }, failedHandler: () {
          debugPrint("ALDownloader | 下载失败, url = $url\n");
        }, pausedHandler: () {
          debugPrint("ALDownloader | 下载暂停, url = $url\n");
        }));
    
    /// 添加一个下载句柄池
    ALDownloader.addDownloaderHandlerInterface(
        ALDownloaderHandlerInterface(progressHandler: (progress) {
          debugPrint(
              "ALDownloader | 下载进度 = $progress, url = $url\n");
        }, succeededHandler: () {
          debugPrint("ALDownloader | 下载成功, url = $url\n");
        }, failedHandler: () {
          debugPrint("ALDownloader | 下载失败, url = $url\n");
        }, pausedHandler: () {
          debugPrint("ALDownloader | 下载暂停, url = $url\n");
        }),
        url);
    
    /// 添加一个持久下载句柄池
    ALDownloader.addForeverDownloaderHandlerInterface(
        ALDownloaderHandlerInterface(progressHandler: (progress) {
          debugPrint(
              "ALDownloader | 下载进度 = $progress, url = $url\n");
        }, succeededHandler: () {
          debugPrint("ALDownloader | 下载成功, url = $url\n");
        }, failedHandler: () {
          debugPrint("ALDownloader | 下载失败, url = $url\n");
        }, pausedHandler: () {
          debugPrint("ALDownloader | 下载暂停, url = $url\n");
        }),
        url);
    
    /// 移除下载句柄池
    ALDownloader.removeDownloaderHandlerInterfaceForUrl(url);
    
    /// 获取下载状态
    final status = ALDownloader.getDownloadStatusForUrl(url);
    
    /// 获取下载进度
    final progress = ALDownloader.getDownloadProgressForUrl(url);
    
    /// 暂停下载
    ///
    /// 停止下载,不删除未下载完成的数据
    await ALDownloader.pause(url);
    
    /// 取消下载
    ///
    /// 停止下载,删除未下载完成的数据
    await ALDownloader.cancel(url);
    
    /// 移除下载
    ///
    /// 删除下载,删除所有数据
    await ALDownloader.remove(url);
    

    ALDownloaderBatcher

    /// 批量下载
    await ALDownloaderBatcher.downloadUrls(urls,
        downloaderHandlerInterface:
            ALDownloaderHandlerInterface(progressHandler: (progress) {
          debugPrint("ALDownloader | 批量 | 下载进度 = $progress\n");
        }, succeededHandler: () {
          debugPrint("ALDownloader | 批量 | 下载成功\n");
        }, failedHandler: () {
          debugPrint("ALDownloader | 批量 | 下载失败\n");
        }, pausedHandler: () {
          debugPrint("ALDownloader | 批量 | 下载暂停\n");
        }));
    
    /// 对批量下载添加一个下载句柄池
    ALDownloaderBatcher.addDownloaderHandlerInterface(
        ALDownloaderHandlerInterface(progressHandler: (progress) {
          debugPrint("ALDownloader | 批量 | 下载进度 = $progress\n");
        }, succeededHandler: () {
          debugPrint("ALDownloader | 批量 | 下载成功\n");
        }, failedHandler: () {
          debugPrint("ALDownloader | 批量 | 下载失败\n");
        }, pausedHandler: () {
          debugPrint("ALDownloader | 批量 | 下载暂停\n");
        }),
        urls);
    
    /// 获取一组url的下载状态
    final status = ALDownloaderBatcher.getDownloadStatusForUrls(urls);
    

    ALDownloaderPersistentFileManager - 基于url的持久化文件管理器

    final model = await ALDownloaderPersistentFileManager
        .lazyGetALDownloaderPathModelForUrl(url);
    debugPrint(
        "ALDownloader | 获取[url]的“物理目录路径”和“虚拟/物理文件名”, url = $url, model = $model\n");
    
    final path2 = await ALDownloaderPersistentFileManager
        .lazyGetAbsolutePathOfDirectoryForUrl(url);
    debugPrint(
        "ALDownloader | 获取[url]的“物理目录路径”, url = $url, path = $path2\n");
    
    final path3 = await ALDownloaderPersistentFileManager
        .getAbsoluteVirtualPathOfFileForUrl(url);
    debugPrint(
        "ALDownloader | 获取[url]的“虚拟文件路径”, url = $url, path = $path3\n");
    
    final path4 = await ALDownloaderPersistentFileManager
        .getAbsolutePhysicalPathOfFileForUrl(url);
    debugPrint(
        "ALDownloader | 获取[url]的“物理文件路径”, url = $url, path = $path4\n");
    
    final isExist = await ALDownloaderPersistentFileManager
        .isExistAbsolutePhysicalPathOfFileForUrl(url);
    debugPrint(
        "ALDownloader | 检查[url]是否存在“物理文件路径”, url = $url, is Exist = $isExist\n");
    
    final fileName = ALDownloaderPersistentFileManager.getFileNameForUrl(url);
    debugPrint(
        "ALDownloader | 获取[url]的“虚拟/物理文件名”, url = $url, file name = $fileName\n");
    

    ALDownloaderPrintConfig

    /// 开启打印
    ALDownloaderPrintConfig.enabled = true;
    
    /// 关闭频繁打印
    ALDownloaderPrintConfig.frequentEnabled = false;
    

    提示:

    1. 在一个协程中,方法需要await修饰

    例如:

    Future<void> executeSomeMethodsTogetherSerially() async {
      await ALDownloader.initialize();
      await ALDownloader.remove(url);
      await ALDownloader.download(url);
    }
    

    2. 如果持久化文件被一些异常方式删除了,比如某些业务代码删除了缓存文件夹,调用[remove],然后调用[download]重新下载来解决这个问题

    Example的主要文件

    iOS

    Android

    Maintainer: jackleemeta (jackleemeta@outlook.com)

    相关文章

      网友评论

        本文标题:Flutter 下载器 al_downloader

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