RxJava2和Retrofit2用的越来越多,最近也在封装一个通用的网络请求库,其中就包括了单文件下载的方法,所以这里进行记录。文末附带Demo

由于网上很多的方法都是使用拦截器进行进度的监听,个人觉得使用起来非常复杂和,所以取了个巧,在文件写入到硬盘的时候对文件读写进行监听,就解决了retrofit2下载文件没有进度监听的问题。

先上封装之后的使用代码,使用简单,直接回调下载之后的文件

封装步骤

  • 1.定义接口(使用的时候传入完整的url,@Streaming注解可用于下载大文件)
  1. @Streaming
  2. @GET
  3. Observable<ResponseBody> downLoadFile(@NonNull @Url String url);
  • 2.文件下载的回调方法和文件保存方法
  1. public abstract class FileDownLoadObserver<T> extends DefaultObserver<T> {
  2.  
  3. @Override
  4. public void onNext(T t) {
  5. onDownLoadSuccess(t);
  6. }
  7. @Override
  8. public void onError(Throwable e) {
  9. onDownLoadFail(e);
  10. }
  11. //可以重写,具体可由子类实现
  12. @Override
  13. public void onComplete() {
  14. }
  15. //下载成功的回调
  16. public abstract void onDownLoadSuccess(T t);
  17. //下载失败回调
  18. public abstract void onDownLoadFail(Throwable throwable);
  19. //下载进度监听
  20. public abstract void onProgress(int progress,long total);
  21.  
  22. /**
  23. * 将文件写入本地
  24. * @param responseBody 请求结果全体
  25. * @param destFileDir 目标文件夹
  26. * @param destFileName 目标文件名
  27. * @return 写入完成的文件
  28. * @throws IOException IO异常
  29. */
  30. public File saveFile(ResponseBody responseBody, String destFileDir, String destFileName) throws IOException {
  31. InputStream is = null;
  32. byte[] buf = new byte[];
  33. int len = ;
  34. FileOutputStream fos = null;
  35. try {
  36. is = responseBody.byteStream();
  37. final long total = responseBody.contentLength();
  38. long sum = ;
  39.  
  40. File dir = new File(destFileDir);
  41. if (!dir.exists()) {
  42. dir.mkdirs();
  43. }
  44. File file = new File(dir, destFileName);
  45. fos = new FileOutputStream(file);
  46. while ((len = is.read(buf)) != -) {
  47. sum += len;
  48. fos.write(buf, , len);
  49. final long finalSum = sum;
  50. //这里就是对进度的监听回调
  51. onProgress((int) (finalSum * / total),total);
  52. }
  53. fos.flush();
  54.  
  55. return file;
  56.  
  57. } finally {
  58. try {
  59. if (is != null) is.close();
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. }
  63. try {
  64. if (fos != null) fos.close();
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70. }
  • 3.Retorfit构建
  1. /**
  2. * 下载单文件,该方法不支持断点下载
  3. *
  4. * @param url 文件地址
  5. * @param destDir 存储文件夹
  6. * @param fileName 存储文件名
  7. * @param fileDownLoadObserver 监听回调
  8. */
  9. public void downloadFile(@NonNull String url, final String destDir, final String fileName, final FileDownLoadObserver<File> fileDownLoadObserver) {
  10. Retrofit retrofit = new Retrofit.Builder()
  11. .client(new OkHttpClient())
  12. .baseUrl(BASE_API.BASE_URL)
  13. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  14. .addConverterFactory(GsonConverterFactory.create())
  15. .build();
  16. retrofit
  17. .create(BASE_API.class)
  18. .downLoadFile(url)
  19. .subscribeOn(Schedulers.io())//subscribeOn和ObserOn必须在io线程,如果在主线程会出错
  20. .observeOn(Schedulers.io())
  21. .observeOn(Schedulers.computation())//需要
  22. .map(new Function<ResponseBody, File>() {
  23. @Override
  24. public File apply(@NonNull ResponseBody responseBody) throws Exception {
  25. return fileDownLoadObserver.saveFile(responseBody, destDir, fileName);
  26. }
  27. })
  28. .observeOn(AndroidSchedulers.mainThread())
  29. .subscribe(fileDownLoadObserver);
  30. }
  • 4使用,如一开始的图
  1. downloadFile("文件下载url","目标存储路径","文件名",new FileDownLoadObserver<File>() {
  2. @Override
  3. public void onDownLoadSuccess(File file) {
  4. }
  5. @Override
  6. public void onDownLoadFail(Throwable throwable) {
  7. }
  8.  
  9. @Override
  10. public void onProgress(int progress,long total) {
  11. }
  12. });

Android RxJava2+Retrofit2单文件下载监听进度封装的更多相关文章

  1. android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到

    android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到 今天做android上的消息推送,启动了一个独立service,然后在里面监听系统的ACTION ...

  2. android的Home键的监听封装工具类(一)

    android的Home键的监听封装: package com.gzcivil.utils; import android.content.BroadcastReceiver; import andr ...

  3. [Android] Android RxJava2+Retrofit2+OkHttp3 的使用(一) --基础篇 Retrofit2 的使用

    本文是 Android RxJava2+Retrofit2+OkHttp3 的使用(一) --基础篇 Retrofit2 的使用 本文的目标是用 Retrofit写一个网络请求: 本文以从获取天气预报 ...

  4. [Android] Android RxJava2+Retrofit2+OkHttp3 的使用

    [Android] Android RxJava2+Retrofit2+OkHttp3 简单介绍Retrofit.OKHttp和RxJava之间的关系: Retrofit:Retrofit是Squar ...

  5. 使用NSURLSessionDownloadTask实现大文件下载-监听下载进度

    - 5.1 涉及知识点(1)创建NSURLSession并设置代理,通过NSURLSessionDownloadTask并以代理的方式来完成大文件的下载 //1.创建NSURLSession,设置代理 ...

  6. 【Android代码片段之八】监听Android屏幕是否锁屏

    实现方法:1)通过BroadcastReceiver接收广播Intent.ACTION_SCREEN_ON和Intent.ACTION_SCREEN_OFF可以判断屏幕状态是否锁屏,但是只有屏幕状态发 ...

  7. Android Edittext 显示光标 获取焦点 监听焦点

    Edittext java 代码控制获取焦点 EditText mEditText = (EditText) findViewById(R.id.et); mEditText.setFocusable ...

  8. android 呼入电话的监听(来电监听)转

    需要权限: <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 方式一:通过广 ...

  9. 另辟思路解决 Android 4.0.4 不能监听Home键的问题

    问题描述: 自从Android 4.0以后,开发人员是不能监听和屏蔽Home键的,对于KEYCODE_HOME,官方给出的描述如下: Home key. This key is handled by ...

随机推荐

  1. sql语句去重 最后部分没看 看1 有用

    一 数据库 1.常问数据库查询.修改(SQL查询包含筛选查询.聚合查询和链接查询和优化问题,手写SQL语句,例如四个球队比赛,用SQL显示所有比赛组合:举例2:选择重复项,然后去掉重复项:) 数据库里 ...

  2. win7中配置eclipse连接Ubuntu内的hadoop

    Hadoop java 分布式 云计算 数据库 目录[-] 1.设置Ubuntu静态IP: 1)配置网卡参数到interfaces文件: 2)重启网卡: 2.配置Ubuntu的hosts: 3.配置V ...

  3. 使用python内置模块os和openpyxl搜索指定文件夹下Excel中的内容

    在指定路径下,搜索Excel文件中包含的指定内容,首先需要遍历指定路径,得到该路径下所有Excel文件的绝对/相对路径:然后读取Excel中内容,将文件中的每个单元格的值与要搜索的内容进行判断(正则比 ...

  4. 面试问题 - SQL 中存储过程与函数的区别

    SQL 中的存储过程与函数没有本质上的区别 函数 -> 只能返回一个变量. 函数可以嵌入到sql中使用, 可以在select 中调用, 而存储过程不行.  但函数也有着更多的限制,比如不能使用临 ...

  5. 实验楼Linux基础入门第一周

    &&使用oschina的git服务器 1.创建了项目 https://git.oschina.net/abc99/wyq20169314 2.配置项目 (1)为项目添加公钥 项目管理- ...

  6. 机器学习十大算法之EM算法

    此文已由作者赵斌授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 由于目前论坛的Markdown不支持Mathjax,数学公式没法正常识别,文章只能用截图上传了...     ...

  7. LOJ6053 简单的函数(min_25筛)

    题目链接:LOJ 题目大意:从前有个积性函数 $f$ 满足 $f(1)=1,f(p^k)=p\oplus k$.(异或)求其前 $n$ 项的和对 $10^9+7$ 取模的值. $1\le n\le 1 ...

  8. C#多进程并行

    为了并行执行多个任务,可以启动多个进程(并行数). 下面提供两种方法,总任务数10,最大并行数4. 一.方法1 using System; using System.Collections.Gener ...

  9. 一文带你看懂WebSocket 的原理?为什么可以实现持久连接?

    工作之余在知乎上偶然看到一篇回帖,瞬间觉得之前看的那么多资料都不及这一篇让我对 websocket 的认知深刻易懂,之前看总完总觉得一知半解云里雾里.所以与大家共同分享一下一起学习.比较喜欢这种博客理 ...

  10. STP-18-Port-Channl上的负载均衡

    Ether Channel通过在多条链路上传输多个数据帧,增加了可用带宽.一个以太网帧总是通过一个Ether Channel中的一条链路传输.针对数据帧地址字段执行散列计算能够产生一个编号,标识这个数 ...