DownloadManager下载框架实现-简介

简介: 多线程下载;多任务下载;断点续传;自定义网络库;自定义缓存管理;自定义存储路径;灵活易用,几行代码搞定复杂的下载功能;纯原生代码实现,兼容性高

在本公司项目中,下载是广告相关业务不可缺少的一个重要功能,然而由于下载部分的源码没有对其他部门公开,我又感觉公司的框架不好用,所以忙里抽闲,花了大概一周时间,打造了一个自己的下载器,我希望我的下载器不只可以下载apk,也可以下载文本文件,音乐mp3,等等任何一个链接可以启动的下载任务,初具雏形。还没有拿到实际项目中检验,有问题希望大家提出帮我一起来完善这个项目,目前已经提交到GitHub,和JitPack,我们公司的项目肯定没机会使用了,希望能帮到需要的同伴们。(2020/12/07,目前已作为B方案将要应用到公司项目中)

GitHub地址 git@github.com:renzhenming/DownloadModel.git

1.引入

在根build.gradle中配置

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}   

在主工程build.gradle中添加(最新版本见GitHub)

dependencies {
    implementation 'com.github.renzhenming:DownloadModel:1.0.9'
}

这样你的项目中就可以使用我的下载器了

2.支持的功能

a.多线程下载

有些大文件下载的需求中,单线程下载无法满足对效率的追求,此时我想尽可能多的利用硬件资源提高下载速度,那我可以选择开启2个线程3个线程甚至10个线程(只要你内核足够)来下载这一个文件,虽然效率不能说成倍提高,但是作用还是很明显的

b.多文件下载

比如应用市场项目中,可能同时点了多个apk一同下载,你不需要关心别的,只需把每个下载链接都丢给我的下载器即可,然后下载器会告诉你下载状态,你根据状态来更新你的界面显示即可其他的一切交给它来处理。你也可以自定义线程池来管理每一个下载任务,设置下载器的产能,这些接口都通过IThreadPool接口开放出来,你的自主性很高。

c.断点下载

下载是一个相对耗时的任务,下载过程中被中断的可能性很高,所以不能说一旦终端我就要从头开始,这是一个很糟糕的情况。所以一个完善的下载器必须具备断点续传的能力,这也是一个基本的功能。下载过程中你可以主动停止一次下载,也可能是系统原因导致下载被迫中断,但是这些在我的下载器中都不是问题,也不需要你去关心,你需要做的就是丢一个链接进去,其他的不用你考虑

d.自定义下载路径

每个项目下载的存储路径都是不同的,所以必须将下载路径的设置接口开放给使用者,不然这就不能称之为一个通用的框架,不用担心IPath接口已经提供了这一点

e.自定义缓存管理

下载过程中的状态信息需要保存起来,以备后边使用,就以华为应用市场为例,我下载一个app,下载过程中我暂停了,退出到后台看了会新闻,等我再次想起来我还有一个任务在下载,然后再次进来的时候,从缓存中拿到上次的下载节点,我才能看到当前的下载进度。ICache把缓存的读取和写入的能力提供给使用者,你只需要实现这个接口,来处理自己的逻辑即可,当然如果你图省事,直接用我默认的缓存工具即可。

f.线程池管理

每个项目选用的线程池策略也是各有不同的,有的需要单线程顺序下载,有的需要多线程并列执行,所以这里把线程池的接口也开放出来,给使用者自定义的能力,就是上边有提到的IThreadPool接口

g.开放的网络接口

我的代码里网络是直接通过HttpUrlConnection实现的,你可能希望通过HttpsUrlConnection实现或者想用第三方的开源网络框架实现,那么你就可以自定义一个类实现IConnection接口来实现自己的网络,像这种更换频率较高的代码逻辑我会努力将接口公开给使用者

3.Api

简单介绍一下下载器主要的api接口,后边文章会简要介绍实现原理

download(String downloadUrl)

这是一个同步方法,可以保证多线程的安全性,下载器支持多种类型的下载,只需要传入一个downloadUrl,这是唯一的输入内容,我公司的下载器功能比较完善,但是有一点,和业务逻辑耦合太严重,这就导致他的通用性不佳,我这里直接传链接,几乎可以说在任何场景都是可以直接拿来用的

pause(String downloadUrl)

同样是同步的,用来暂停一个下载,这里仍然通过传递url来执行,看似不太合理,但其实也是为了框架的通用性考虑。也许你会说这里传唯一id看着更顺眼点,这样说很对,但是要知道,并不是每一个下载对象都有id ,的,如果我只是下载一张图片,你却要我传个id进去,难不成我要造一个出来?

registerObserver(DownloadObserver observer)

注册观察者,在需要根据下载进度更新ui的地方进行注册,在退相关页面的时候移除注册
unregisterObserver(DownloadObserver observer)
移除观察者,防止内存泄漏

4.使用方法

开启下载

DownloadManager.getInstance(context).download(downloadUrl);

暂停下载

DownloadManager.getInstance(context).pause(downloadUrl);

获取当前下载状态

DownloadInfo downloadInfo = mDownloadManager.getDownloadInfo(downloadUrl);
if (downloadInfo == null) {
   // 没有下载过
    mCurrentState = DownloadManager.STATE_NONE;
    mProgress = 0;
} else {
    // 之前下载过, 以缓存中的对象的状态为准
    mCurrentState = downloadInfo.currentState;
    mProgress = downloadInfo.getProgress();
}

监听下载状态

DownloadManager.getInstance(context).registerObserver(new DownloadManager.DownloadObserver() {
     @Override
     public void onDownloadStateChanged(DownloadInfo info) {
               
     }

     @Override
     public void onDownloadProgressChanged(DownloadInfo info) {

     }
});

移除监听

DownloadManager.getInstance(context).unregisterObserver(downloadObserver);

5.总结

本篇着重使用方面的介绍,后边会进行内部代码的简单分析

相关文章
|
5月前
|
XML Java Android开发
Android Studio App开发之下载管理器DownloadManager中显示、轮询下载进度、利用POST上传文件讲解及实战(附源码)
Android Studio App开发之下载管理器DownloadManager中显示、轮询下载进度、利用POST上传文件讲解及实战(附源码)
394 0
|
JavaScript Linux 开发工具
APICloud-Tools-Core-APICloud 开发工具核心库
APICloud 开发工具核心库,支持新建页面模板,新建应用模板,WiFi 同步等核心功能。 开发者可基于此核心库,定制各种编辑器插件或者将 APICloud 的开发调试功能与已有的自动化业务流程结合,提升开发效率。
135 0
DownloadManager下载框架实现-源码
多线程下载;多任务下载;断点续传;自定义网络库;自定义缓存管理;自定义存储路径;灵活易用,几行代码搞定复杂的下载功能;纯原生代码实现,兼容性高
1028 0