Android 实现简易下载管理器 (暂停、断点续传、多线程下载)

什么都先别说,先看预览图!

这里写图片描述

预览图中是限制了同时最大下载数为 2 的.

其实下载管理器的实现是挺简单的,我们需要弄清楚几点就行了

1.所有任务的Bean应该存在哪里,用什么存?
2.如何判断任务是否已存在?
3.如何判断任务是新的任务或是从等待中恢复的任务?
4.应该如何把下载列表传递给Adapter?
5.如何将下载的进度传递出去?
6.如何有效率地刷新显示的列表? (ListView 或 RecycleView)

服务基础

首先我们需要明确一点,下载我们应该使用服务来进行,这样我们才能进行后台下载。
所以我们就开始创建我们的Service:

public class OCDownloadService extends Service{
   

    ... ...

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //当服务被Bind的时候我们就返回一个带有服务对象的类给Bind服务的Activity
        return new GetServiceClass();
    }

    /**
     * 传递服务对象的类
     */
    public class GetServiceClass extends Binder{
   

        public OCDownloadService getService(){
            return OCDownloadService.this;
        }

    }
    ... ...
}

然后我们在AndroidManifest.xml里面注册一下:

<service android:name=".OCDownloader.OCDownloadService"/>

下载请求的检查与处理

然后我们就开始进入正题 !
首先第一点,我们使用HashMap来当作储存下载任务信息的总表,这样的好处是我们可以在查找任务的时候通过 Key 来查询,而不需要通过遍历 List 的方法来获取任务信息。而且我们传递的时候可以直接使用它的一份Copy就行了,不需要把自己传出去。

下面我们来看代码:

(关于Service的生命周期啥的我就不再重复说了。我这里使用的是本地广播来传输下载信息的更新。剩下的在代码注释中有详细的解释)

public class OCDownloadService extends Service{
   

    static final int MAX_DOWNLOADING_TASK = 2; //最大同时下载数
    private LocalBroadcastManager broadcastManager;
    private HashMap<String,DLBean> allTaskList;
    private OCThreadExecutor threadExecutor;

    private boolean keepAlive = false;
    private int runningThread = 0;

    @Override
    public void onCreate() {
        super.onCreate();

        //创建任务线程池
        if (threadExecutor == null){
            threadExecutor = new OCThreadExecutor(MAX_DOWNLOADING_TASK,"downloading");
        }

        //创建总表对象
        if (allTaskList == null){
            allTaskList = new HashMap<>();
        }

        //创建本地广播器
        if (broadcastManager == null){
            broadcastManager = LocalBroadcastManager.getInstance(this);
        }
    }

    /**
     * 下载的请求就是从这里传进来的,我们在这里进行下载任务的前期处理
     */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        //检测传过来的请求是否完整。我们只需要 下载网址、文件名、下载路径 即可。
        if (intent != null && intent.getAction() != null && intent.getAction().equals("NewTask")){
            String url = intent.getExtras().getString("url");
            String title = intent.getExtras().getString("title");
            String path = intent.getExtras().getString("path");

            //检测得到的数据是否有效
            if (TextUtils.isEmpty(url) || TextUtils.isEmpty(title) || TextUtils.isEmpty(path)){
                Toast.makeText(OCDownloadService.this,"Invail data",Toast.LENGTH_SHORT).show();
                return super.onStartCommand(intent, flags, startId);
            }else {

                //如果有效则执行检查步骤
                checkTask(new DLBean(title,url,path));
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }

    /**
     * 检查新的下载任务
     * @param requestBean   下载对象的信息Bean
     */
    private synchronized void checkTask(@Nullable DLBean requestBean){
        if (requestBean != null){

            //先检查是否存在同名的文件
            if (new File(requestBean.getPath()+"/"+requestBean.getTitle()).exists()){
                Toast.
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值