2019独角兽企业重金招聘Python工程师标准>>>

OKHttp3 是如今非常流行的 Android 网络请求框架,那么如何利用 Android 实现断点续传呢,今天写了个 Demo 尝试了一下。

我们会用到 OKHttp3 来做网络请求,使用 RxJava 来实现线程的切换,并且开启 Java8 来启用 Lambda 表达式,毕竟 RxJava 实现线程切换非常方便,而且数据流的形式也非常舒服,同时 Lambda 和 RxJava 配合食用味道更佳。

打开我们的 app Module 下的 build.gradle,代码如下:

OKHttp 和 RxJava,RxAndroid 使用的都是最新的版本,并且配置开启了 Java8.

布局文件

接着开始书写布局文件:

其他都差不多,大概是这个样子的:

3个ProgressBar就是为了显示进度的,每个 ProgressBar 对应 2个Button,一个是开始下载,一个是暂停(取消)下载,这里需要说明的是,对下载来说暂停和取消没有什么区别,除非当取消的时候,会顺带把临时文件都删除了,在本例里是不区分他俩的.

Application

我们这里需要用到一些文件路径,有一个 全局Context 会比较方便, 而 Application 也是 Context 的子类,使用它的是最方便的,所以我们写一个类来继承:

可以看到,我们就是要获得一个全局的Context对象的

我们在 AndroidManifest 中注册一下我们的 Application,同时再把我们所需要的权限给上,我们只需要一个网络权限:

DownloadManager

接下来是核心代码了,就是我们的 DownloadManager,先上代码:

代码稍微有点长,关键部位我都加了注释了,我们挑关键地方看看

首先我们这个类是单例类,我们下载只需要一个 OKHttpClient 就足够了,所以我们让构造方法私有,而单例类的获取实例方法就是这个 getInstance(); 当然大家用别的方式实现单例也可以的,然后我们在构造方法里初始化我们的 HttpClient,并且初始化一个 HashMap,用来放所有的网络请求的,这样当我们取消下载的时候,就可以找到url对应的网络请求然后把它取消掉就可以了

接下来就是核心的 download 方法了,首先是参数,第一个参数url不用多说,就是请求的网址,第二个参数是一个Observer对象,因为我们使用的是 RxJava,并且没有特别多复杂的方法,所以就没单独写接口,而是谢了一个 Observer对象 来作为回调,接下来是 DownLoadObserver的代码:

在 RxJava2 中这个 Observer 有点变化,当注册观察者的时候,会调用 onSubscribe方法,而该方法参数就是用来取消注册的,这样的改动可以更灵活的有监听者来取消监听了,我们的进度信息会一直的传送的 onNext方法 里,这里将下载所需要的内容封了一个类叫 DownloadInfo:

这个类就是一些基本信息,total 就是需要下载的文件的总大小,而 progress 就是当前下载的进度了,这样就可以计算出下载的进度信息了

接着看 DownloadManager 的 download 方法,首先通过 url 生成一个 Observable对象,然后通过 filter 操作符过滤一下,如果当前正在下载这个url对应的内容,那么就不下载它。

接下来调用 createDownInfo 重新生成 Observable对象,这里应该用map也是可以的,createDownInfo 这个方法里会调用 getContentLength 来获取服务器上的文件大小,可以看一下这个方法的代码:

可以看到,其实就是在通过 OK 进行了一次网络请求,并且从返回的头信息里拿到文件的大小信息,一般这个信息都是可以拿到的,除非下载网址不是直接指向资源文件的,而是自己手写的 Servlet,那就得跟后台人员沟通好了.注意,这次网络请求并没有真正的去下载文件,而是请求个大小就结束了,具体原因会在后面真正请求数据的时候解释

接着 download方法,获取完文件大小后,就可以去硬盘里找文件了,这里调用了 getRealFileName 方法:

这个方法就是看本地是否有已经下载过的文件,如果有,再判断一次本地文件的大小和服务器上数据的大小,如果是一样的,证明之前下载全了,就再成一个带(1)这样的文件,而如果本地文件大小比服务器上的小的话,那么证明之前下载了一半断掉了,那么就把进度信息保存上,并把文件名也存上,看完了再回到 download 方法

之后就开始真正的网络请求了,这里写了一个内部类来实现 ObservableOnSubscribe接口,这个接口也是 RxJava2 的,东西和之前一样,好像只改了名字,看一下代码:

主要看 subscribe 方法。首先拿到 url,当前进度信息和文件的总大小,然后开始网络请求,注意这次网络请求的时候需要添加一条头信息:

.addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength)

这条头信息的意思是下载的范围是多少,downloadLength 是从哪开始下载,contentLength 是下载到哪,当要断点续传的话必须添加这个头,让输入流跳过多少字节的形式是不行的,所以我们要想能成功的添加这条信息那么就必须对这个url请求2次,一次拿到总长度,来方便判断本地是否有下载一半的数据,第二次才开始真正的读流进行网络请求。

我还想了一种思路,当文件没有下载完成的时候添加一个自定义的后缀,当下载完成再把这个后缀取消了,应该就不需要请求两次了.

接下来就是正常的网络请求,向本地写文件了,而写文件到本地这,网上大多用的是 RandomAccessFile 这个类,但是如果不涉及到多个部分拼接的话是没必要的,直接使用输出流就好了,在输出流的构造方法上添加一个 true 的参数,代表是在原文件的后面添加数据即可,而在循环里,不断的调用 onNext 方法发送进度信息,当写完了之后别忘了关流,同时把call对象从 hashMap 中移除了.这里写了一个 IOUtil 来关流:

其实就是挨一个判断是否为空,并关闭罢了

这样download方法就完成了,剩下的就是切换线程,注册观察者了

MainActivity

最后是activity的代码:

Activity里没什么了,就是注册监听,开始下载,取消下载这些了,下面我们来看看效果吧:

可以看到 多个下载,断点续传什么的都已经成功了,最后我的文件网址是我自己的局域网,大家写的时候别忘了换了..

代码地址:

http://download.csdn.net/detail/cfy137000/9746583

转载于:https://my.oschina.net/JiangTun/blog/911439

使用OKHttp3实现下载(断点续传、显示进度)相关推荐

  1. python下载文件加上日期_Python实现给下载文件显示进度条和下载时间代码

    本篇文章小编给大家分享一下Python实现给下载文件显示进度条和下载时间代码,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 该模块调用了三个库: 1. ...

  2. php 判断下载状态,php下载文件显示进度(适用于CLI模式或长连接)

    代码: /* @desc:php下载文件显示进度 @param file 待下载文件名 @param name 存储到本地文件名 */ function downloadprogress($file, ...

  3. VC下载文件 + 显示进度条

    在codeproject里找了许久,发现这样一个VC下载文件并显示进度条的源码,于是添加了些中文注释: 1.下载线程函数: UINT DownloadFile(LPVOID pParam) { CWn ...

  4. Python 给下载文件显示进度条和下载时间(一看就会!)

    其实实现它方法很简单,这里我写了个进度条的模块,其中还附带上了运行时间也就是下载时间了. 该模块调用了三个库: 1.os 2.requests 3.time 话不多说,先上代码!!!. # 进度条模块 ...

  5. 如何异步下载图片显示进度条

    本文案例中,使用原生协程结合requests库,而requests库本身不支持异步请求方式.但可以使用协程对象将requests库包装,运用协程executor对象使其requests库支持异步请求. ...

  6. Android实现下载文件(图片)显示进度

    这里是做笔记用,不做过多介绍: 1.布局代码:download.xml <?xml version="1.0" encoding="utf-8"?> ...

  7. python3.6进度条_Python实现下载界面(带进度条,断点续传,多线程多任务下载等)...

    开发环境: Windows 7 64位,Python 3.6.2 实现功能: 进度条,下载速度和下载进度的显示,断点续传(暂停继续下载功能),取消下载等功能 下载界面,如图所示 点击'新建任务',弹出 ...

  8. php显示服务器文件,php-无法显示从新服务器下载文件的进度(在以前的服务器上工作)...

    我一直在开发iPad应用程序,该应用程序使用ASIHTTPRequest下载一些PDF文件.我一直在使用进度委托来为用户显示进度条,以显示文件的下载进度.这是ASIHTTPRequest设置代码. r ...

  9. linux ftp显示进度条,在Python中显示FTP下载进度(ProgressBar)

    我使用以下Python脚本通过FTP下载文件.我想要的是在下载时查看进度的详细信息.为此,我使用了ProgressBar但它没有显示任何内容. 这是我的代码: import re import os ...

最新文章

  1. Java BufferImage图片处理(获取宽高、图片截取、转换灰度图)
  2. ios 扑克牌效果轮播_iOS一行代码实现立体轮播图
  3. Vue为v-html中标签添加CSS样式
  4. MFC对话框中的工具栏、状态栏设计小结
  5. Android 5.1 API 22 所有sdk文件下载地址
  6. 洛谷 1137 旅行计划
  7. java建立线性表的链式结构,数据结构学习----线性表的链式表示(Java实现)
  8. H5 71-网易注册界面4
  9. 多线程模拟实现生产者/消费者模型 (借鉴)
  10. Delphi2007中安装OCX控件
  11. JNI 在实际项目中的使用方法
  12. Linux 安装ifconfig命令
  13. 受力分析软件_基于非线性分析的建筑结构设计与优化
  14. C语言 逻辑运算符及其优先级
  15. 如何在中国大陆三大运营商申请公网IPV4地址
  16. linux返回上级目录
  17. 鸿蒙系统图标显示下划线,用鸿蒙OS在蜂鸣器上播放一曲《两只老虎》
  18. SpringBoot 集成SpringSecurity整体流程
  19. excel怎么从身份证中提取性别?
  20. EF6 T4 Model.TT文件的修改-自动加上注释

热门文章

  1. 疯狂的程序员-第五章
  2. MAC版Pycharm主题——WarmColor
  3. c将字符串拆分,并存入结构体
  4. C#显示相机实时画面
  5. spring 获取 WebApplicationContext的几种方法
  6. 【贪心】【codeforces】651A Joysticks
  7. 使用设置报头x-Frame-Options限制iframe网页嵌套
  8. WebConfig自定义节点并读取
  9. Keep Walking!
  10. csv文件简介(转载)