基于Ok+Rxjava实现断点续传下载

本文为大家分享了实现断点续传下载的具体代码,供大家参考,具体内容如下

1、基于Ok+Rxjava实现断点续传下载

2、基于Ok+Rxjava+Retrofit实现断点续传下载

最近总结一下了一下之前学过以及用到过得功能,整理了一个基于Ok+Rxjava实现断点续传下载的demo。下面先给大家展示一下使用效果吧。

说下我的大致思路吧:根据文件下载url按照自己定义的规则生成文件名,判断本地同路径下是否存在此文件,如果存在,文件大小与服务器上获取的文件大小一致的情况下,则生成新的文件名重新下载;如果文件比服务器获取的文件大小小,则执行断点下载,从本地文件长度处开始下载。如果文件不存在,则从0字节开始下载。

DownloadSubscribe(被观察者)中执行下载存入本地操作

核心还是:addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength)

DownLoadObserver(观察者)通过onnext(DownloadInfo downloadInfo)方法回调下载进度

下面上主要代码:

/**
  * 开始下载
  * @param url    下载请求的网址
  * @param downFileCallback 用来回调的接口
  */
 public void download(final String url, final DownFileCallback downFileCallback) {
  if (url == null || downCalls.get(url) != null) {
   return;
  }
  Observable.just(url)
    .filter(new Predicate<String>() {
     @Override
     public boolean test(String s) throws Exception {
      //过滤条件 若map中存在,则这次不下载
      return !downCalls.containsKey(s);
     }
    })
    .flatMap(new Function<String, ObservableSource<DownloadInfo>>() {
     @Override
     public ObservableSource<DownloadInfo> apply(String s) throws Exception {
      //创建下载实体类
      return Observable.just(createDownInfo(s));
     }
    })
    .map(new Function<DownloadInfo, DownloadInfo>() {
     @Override
     public DownloadInfo apply(DownloadInfo s) throws Exception {
      //根据本地是否存在此文件,来设置文件名及文件初始下载大小
      return getRealFileName(s);
     }
    })
    .flatMap(new Function<DownloadInfo, ObservableSource<DownloadInfo>>() {
     @Override
     public ObservableSource<DownloadInfo> apply(DownloadInfo downloadInfo) throws Exception {
       //创建被观察者
      return Observable.create(new DownloadSubscribe(downloadInfo));
     }
    })//下载
    .observeOn(AndroidSchedulers.mainThread())//在主线程回调
    .subscribeOn(Schedulers.io())//在子线程执行
    .subscribe(new DownLoadObserver() {//添加观察者
     @Override
     public void onNext(DownloadInfo downloadInfo) {
      super.onNext(downloadInfo);
      downFileCallback.onProgress(downloadInfo.getTotal(), downloadInfo.getProgress());
     }

     @Override
     public void onError(Throwable e) {
      super.onError(e);
      if (!(e instanceof SocketException)) {
       downFileCallback.onFail(e.getMessage());
      }

     }

     @Override
     public void onComplete() {
      downFileCallback.onSuccess(url);
     }

    });
 }
/**
 * 根据url暂停下载操作
 * @param url
 */
 public void cancel(String url) {
  Call call = downCalls.get(url);
  if (call != null) {
   call.cancel();//取消
  }
  downCalls.remove(url);
 }
 /**
  * 创建被观察者DownloadSubscribe
  */
 private class DownloadSubscribe implements ObservableOnSubscribe<DownloadInfo> {
  private DownloadInfo downloadInfo;

  public DownloadSubscribe(DownloadInfo downloadInfo) {
   this.downloadInfo = downloadInfo;
  }

  @Override
  public void subscribe(ObservableEmitter<DownloadInfo> e) throws Exception {
   String url = downloadInfo.getUrl();
   long downloadLength = downloadInfo.getProgress();//已经下载好的长度
   long contentLength = downloadInfo.getTotal();//文件的总长度
   //初始进度信息
   e.onNext(downloadInfo);

   Request request = new Request.Builder()
     //断点续传的核心
     .addHeader("RANGE", "bytes=" + downloadLength + "-" + contentLength)
     .url(url)
     .build();
   Call call = mClient.newCall(request);
   //根据下载url,把call存放在map中,取消的时候就可以通过call.cancle()来实现
   downCalls.put(url, call);
   Response response = call.execute();

   File file = new File(getTemporaryPath(), downloadInfo.getFileName());
   InputStream is = null;
   FileOutputStream fileOutputStream = null;
   try {
    is = response.body().byteStream();
    fileOutputStream = new FileOutputStream(file, true);
    byte[] buffer = new byte[2048];//缓冲数组2kB
    int len;
    while ((len = is.read(buffer)) != -1) {
     fileOutputStream.write(buffer, 0, len);
     downloadLength += len;
     downloadInfo.setProgress(downloadLength);
     e.onNext(downloadInfo);
    }
    fileOutputStream.flush();
    downCalls.remove(url);
   } finally {
    //关闭IO流
    IOUtil.closeAll(is, fileOutputStream);

   }
   e.onComplete();//完成
  }
 }
/**
  * 从服务器获取文件长度
  *
  * @param downloadUrl
  * @return
  */
 private long getContentLength(String downloadUrl) {
  Request request = new Request.Builder()
    .url(downloadUrl)
    .build();
  try {
   Response response = mClient.newCall(request).execute();
   if (response != null && response.isSuccessful()) {
    long contentLength = response.body().contentLength();
    response.close();
    return contentLength == 0 ? DownloadInfo.TOTAL_ERROR : contentLength;
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
  return DownloadInfo.TOTAL_ERROR;
 }

从服务器获取文件长度的时候注意一下,Android P之后,也就是api 28以上禁止明文网络传输。需要在你的AndroidManifest中的application标签中声明"android:usesCleartextTraffic="true",允许应用进行明文传输。

使用方法:首先要获取sd卡权限

DownloadManager.getInstance().downloadPath(本地存在地址).download(url1, new DownFileCallback() {
     @Override
     public void onProgress(long totalSize, long downSize) {
      progress1.setMax((int) totalSize);
      progress1.setProgress((int) downSize);
     }

     @Override
     public void onSuccess(String url) {
      Toast.makeText(MainActivity.this, url1 + "下载完成", Toast.LENGTH_SHORT).show();
     }

     @Override
     public void onFail(String msg) {
      Toast.makeText(MainActivity.this, url1 + "下载失败", Toast.LENGTH_SHORT).show();
     }
    });

好了今天就到这里,希望能帮到大家,这对我来说也是一种加深印象的笔记,

下载地址demo

git地址:DownloadManager 欢迎star

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • RxJava+Retrofit+OkHttp实现多文件下载之断点续传

    背景 断点续传下载一直是移动开发中必不可少的一项重要的技术,同样的Rxjava和Retrofit的结合让这个技术解决起来更加的灵活,我们完全可以封装一个适合自的下载框架,简单而且安全! 效果 实现 下载和之前的http请求可以相互独立,所以我们单独给download建立一个工程moudel处理 1.创建service接口 和以前一样,先写接口 注意:Streaming是判断是否写入内存的标示,如果小文件可以考虑不写,一般情况必须写:下载地址需要通过@url动态指定(不适固定的),@head标签是

  • 基于Ok+Rxjava实现断点续传下载

    本文为大家分享了实现断点续传下载的具体代码,供大家参考,具体内容如下 1.基于Ok+Rxjava实现断点续传下载 2.基于Ok+Rxjava+Retrofit实现断点续传下载 最近总结一下了一下之前学过以及用到过得功能,整理了一个基于Ok+Rxjava实现断点续传下载的demo.下面先给大家展示一下使用效果吧. 说下我的大致思路吧:根据文件下载url按照自己定义的规则生成文件名,判断本地同路径下是否存在此文件,如果存在,文件大小与服务器上获取的文件大小一致的情况下,则生成新的文件名重新下载:如果

  • 基于Ok+Rxjava+retrofit实现断点续传下载

    本文为大家分享了实现断点续传下载的具体代码,供大家参考,具体内容如下 1.基于Ok+Rxjava实现断点续传下载 2.基于Ok+Rxjava+Retrofit实现断点续传下载 上一篇博客中介绍了基于Ok+Rxjava实现断点续传下载,这一篇给大家介绍下基于Ok+Rxjava+Retrofit实现断点续传下载,demo下载地址,效果图跟上一篇图片一样,哈哈 说下我的大致思路吧(跟上一篇略有不同):根据文件下载url按照自己定义的规则生成文件名,判断本地同路径下是否存在此文件,如果存在,文件大小与服

  • 基于断点续传下载原理的实现

    需求背景 动态创建的文件下载的时候希望浏览器显示下载进度 动态创建的文件希望能够分段下载 HTTP断点续传报文 要实现HTTP断点续传必须要简单了解以下几个报文. Accept-Ranges 告诉客户端(浏览器..)服务器端支持断点续传 服务器端返回 Range 客户端告诉服务器端从指定的的位置/范围(这里值字节数)下载资源 客户端发出 Content-Range 服务器端告诉客户端响应的数据信息,在整个返回体中本部分的字节位置 服务器端返回 ETag 资源标识 非必须 服务器端返回 Last-

  • 基于Retrofit+Rxjava实现带进度显示的下载文件

    本文实例为大家分享了Retrofit Rxjava实现下载文件的具体代码,供大家参考,具体内容如下 本文采用 :retrofit + rxjava 1.引入: //rxJava compile 'io.reactivex:rxjava:latest.release' compile 'io.reactivex:rxandroid:latest.release' //network - squareup compile 'com.squareup.retrofit2:retrofit:latest

  • Android多线程断点续传下载示例详解

    一.概述 在上一篇博文<Android多线程下载示例>中,我们讲解了如何实现Android的多线程下载功能,通过将整个文件分成多个数据块,开启多个线程,让每个线程分别下载一个相应的数据块来实现多线程下载的功能.多线程下载中,可以将下载这个耗时的操作放在子线程中执行,即不阻塞主线程,又符合Android开发的设计规范. 但是当下载的过程当中突然出现手机卡死,或者网络中断,手机电量不足关机的现象,这时,当手机可以正常使用后,如果重新下载文件,似乎不太符合大多数用户的心理期望,那如何实现当手机可以正

  • java实现文件断点续传下载功能

    本文实例为大家分享了java断点续传下载的代码,供大家参考,具体内容如下 1. Java代码     //实现文件下载功能 public String downloadFile(){ File dir = new File(filepath);//获取文件路劲 if(!dir.exists()) { System.out.println("文件路径错误"); log.debug("文件路径错误"); return "failed";// 判断文件

  • Android编程开发实现多线程断点续传下载器实例

    本文实例讲述了Android编程开发实现多线程断点续传下载器.分享给大家供大家参考,具体如下: 使用多线程断点续传下载器在下载的时候多个线程并发可以占用服务器端更多资源,从而加快下载速度,在下载过程中记录每个线程已拷贝数据的数量,如果下载中断,比如无信号断线.电量不足等情况下,这就需要使用到断点续传功能,下次启动时从记录位置继续下载,可避免重复部分的下载.这里采用数据库来记录下载的进度. 效果图:   断点续传 1.断点续传需要在下载过程中记录每条线程的下载进度 2.每次下载开始之前先读取数据库

  • PHP简单实现断点续传下载的方法

    本文实例讲述了PHP实现断点续传下载的方法.分享给大家供大家参考.具体如下: $fname = 'http://XXXX/MMLDZG.mp3'; $fp = fopen($fname,'rb'); $fsize = filesize($fname); if (isset($_SERVER['HTTP_RANGE']) && ($_SERVER['HTTP_RANGE'] != "") && preg_match("/^bytes=([0-9]

  • Python使用urllib2模块实现断点续传下载的方法

    本文实例讲述了Python使用urllib2模块实现断点续传下载的方法.分享给大家供大家参考.具体分析如下: 在使用HTTP协议进行下载的时候只需要在头上设置一下Range的范围就可以进行断点续传下载,当然,首先服务器需要支持断点续传. 利用Python的urllib2模块完成断点续传下载的例子: #!/usr/bin/python # -*- coding: UTF-8 -* ''' Created on 2013-04-15 Created by RobinTang A demo for R

  • Android通过HTTP协议实现断点续传下载实例

    整理文档,搜刮出一个Android通过HTTP协议实现断点续传下载的代码,稍微整理精简一下做下分享. FileDownloader.java package cn.itcast.net.download; import java.io.File; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; import java.util.LinkedHashMap; impor

随机推荐