美文网首页网络Android开发感悟Android developing tips
Retrofit2的再封装实战—多线程下载与断点续传(一)

Retrofit2的再封装实战—多线程下载与断点续传(一)

作者: Leinyo | 来源:发表于2016-11-01 20:49 被阅读9211次
    monkey.gif

    点下载有等待时间,是因为我设置了每下载1m才回调。

    正题

    基础概念

    一、什么是多线程下载?

    Android主线程是不建议阻塞的,通常的思路,我们下载文件,都是在线程中执行,一个线程对应一个下载通道,如果文件有上百M大小,况且你的网络状态不够好,应该怎么办呢?想一下如果我们把一个100M的文件,拆成4个线程,同时下载,那该是多么幸福的事情啊。无论是效率还是时间上,都会有大幅度的提升。那么在http上怎么实现分段下载呢?很简单 在请求头上加入Range属性,像这样设置bytes范围就可以了。


    Range.png

    现在Response Body就会返回对应范围的字节流了。好了,现在我们来拓展NetWorkRequest类,加入Download接口。

       @Streaming   
       @GET    
      Call<ResponseBody> downloadFile(@Url String fileUrl,@Header("Range") String range);
    }```
    在NetWorkRequest中的中加入获得DownLoadService接口代理类的方法,在init中初始化DownLoadService:
    ```mDownLoadService = mRetrofit.create(DownLoadService.class);```
    向外提供mDownLoadService引用:
    ```public DownLoadService getDownLoadService() {
        return mDownLoadService;
    }```
    好了,关于DownLoadService的初始化就结束了。
    
    #####二、什么是断点续传?
    简单解释就是 从哪摔倒的接着从哪站起来 这就意味着我们可以做取消、继续下载的功能,或者从异常情况下恢复的再下载功能。
    关于如何保持下载数据问题,其实就是如何选择数据持久化方式的问题。
    Android数据持久化方式 Preferences  SQL  I/O ContentProvider,这里选择SQL应该是没有任何异议的,至于你是选择如何实现SQL功能,GreenDao还是Realm或者其他开源项目,这里不做推荐,只要能够实现简单的增删改查功能就好,我选择了原生的sqllite。只为了实现简单功能,并未做完整封装,不考虑借鉴我的sqllite。
    
    ####程序结构
    介绍了基本概念的理解,相信大家对本次实战的内容应该有大体了解了。下面上简单的项目结构图并说一下思路:
    ![结构图.jpeg](http:https://img.haomeiwen.com/i3376157/c16a695249dde192.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    Action:为行动的意思,这里代表我们的Activity,Fragment,或者是Service。A、B即代表着两次请求行为。
    
    DownLoadManager:不同的Action,通过统一入口DownLoadManager调用下载功能,DownLoadManager是单列的。只提供唯一入口,就像很多开源框架Glide.with()、ImageLoader.load()一样,这里是一个设计思路,外观模式,也称为门面模式,大家设计框架时候尽量这样来做,只提供一个入口,即为了以后好维护,也减少了耦合性。我们里面代码再怎么修改,也并不影响外面的调用。不要改一动全身那就尴尬了。DownLoadManager提供创建createRequest方法,我们把每个Action的所有下载任务封装为一个Request,DownLoadManager中只负责创建和取消下载任务,并维护下载任务的缓存。
    
    Request:上面说道,Request即为一次下载任务。每个Request里面可能有几十,甚至上百个url,每个url可能又会因为数据太大而分为多线程任务。每个Request里面维护着所有任务的缓存,基本的逻辑判断,数据持久化都在Request里面,所以这是最有含金量的部分,怎么做到性能最优,怎么做到多线程数据的安全性,都在这里面。
    
    Task:每个url即为一个Task,通过Retrofit调用DownLoad接口,并进行数据存储操作,这里并没有什么难度,只需要通过判断不用的情况,返回不通的状态值,对数据进行不同的操作。同时,根据你的业务逻辑,来适配不通IOException行为。
    
    简单来讲,入口类DownLoadManager,调用者只需要关心这一个类,创建下载任务,DownLoadManager把每个任务封装成一个Request对象,复杂的逻辑判断全部交给Request来做,Task是真正执行下载任务的对象,数据回调从下向上依次传递回Action。
    
    ####文章计划
    写到这里,我想我介绍的思路应该已经很清晰了,本次内容分为三个部分介绍。第一部分到这就结束了,只要是讲一下概念和思路和DownloadService的初始化,觉得有意思的朋友可以根据我上文说的思路,设计一下。下面两篇文章是这样计划的,第二篇从DownloadTask和DownloadManager入口,最后一篇放到重要的Request上,如果您感兴趣,可以关注下这个系列。

    相关文章

      网友评论

      • b0ac01817146:想一下如果我们把一个100M的文件,拆成4个线程,同时下载,那该是多么幸福的事情啊。无论是效率还是时间上,都会有大幅度的提升。
        想不明白这句话,下载速度不应该是主要受网络影响吗,带宽影响。
        多开线程反而不易管理,增加功耗等。
      • 85ae9043b5b9:精辟 :+1: :+1: :+1: 学习了
      • AndroidHarry:楼主你的代码在第一篇的地方给出来了? 就是这个下载?
        Leinyo:@AndroidHarry 如果要代码的话 要等等的 要写的东西实在太多了
        AndroidHarry:@AndroidHarry 那这一篇也没有呀:sweat:
        Leinyo:@AndroidHarry 是的 第一篇没有给出代码

      本文标题:Retrofit2的再封装实战—多线程下载与断点续传(一)

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