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

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

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

封装步骤

  • 1.定义接口(使用的时候传入完整的url,@Streaming注解可用于下载大文件)
@Streaming
@GET
Observable<ResponseBody> downLoadFile(@NonNull @Url String url);
  • 2.文件下载的回调方法和文件保存方法
public abstract class FileDownLoadObserver<T> extends DefaultObserver<T> {

    @Override
public void onNext(T t) {
onDownLoadSuccess(t);
}
@Override
public void onError(Throwable e) {
onDownLoadFail(e);
}
//可以重写,具体可由子类实现
@Override
public void onComplete() {
}
//下载成功的回调
public abstract void onDownLoadSuccess(T t);
//下载失败回调
public abstract void onDownLoadFail(Throwable throwable);
//下载进度监听
public abstract void onProgress(int progress,long total); /**
* 将文件写入本地
* @param responseBody 请求结果全体
* @param destFileDir 目标文件夹
* @param destFileName 目标文件名
* @return 写入完成的文件
* @throws IOException IO异常
*/
public File saveFile(ResponseBody responseBody, String destFileDir, String destFileName) throws IOException {
InputStream is = null;
byte[] buf = new byte[];
int len = ;
FileOutputStream fos = null;
try {
is = responseBody.byteStream();
final long total = responseBody.contentLength();
long sum = ; File dir = new File(destFileDir);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, destFileName);
fos = new FileOutputStream(file);
while ((len = is.read(buf)) != -) {
sum += len;
fos.write(buf, , len);
final long finalSum = sum;
//这里就是对进度的监听回调
onProgress((int) (finalSum * / total),total);
}
fos.flush(); return file; } finally {
try {
if (is != null) is.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
  • 3.Retorfit构建
/**
* 下载单文件,该方法不支持断点下载
*
* @param url 文件地址
* @param destDir 存储文件夹
* @param fileName 存储文件名
* @param fileDownLoadObserver 监听回调
*/
public void downloadFile(@NonNull String url, final String destDir, final String fileName, final FileDownLoadObserver<File> fileDownLoadObserver) {
Retrofit retrofit = new Retrofit.Builder()
.client(new OkHttpClient())
.baseUrl(BASE_API.BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit
.create(BASE_API.class)
.downLoadFile(url)
.subscribeOn(Schedulers.io())//subscribeOn和ObserOn必须在io线程,如果在主线程会出错
.observeOn(Schedulers.io())
.observeOn(Schedulers.computation())//需要
.map(new Function<ResponseBody, File>() {
@Override
public File apply(@NonNull ResponseBody responseBody) throws Exception {
return fileDownLoadObserver.saveFile(responseBody, destDir, fileName);
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(fileDownLoadObserver);
}
  • 4使用,如一开始的图
downloadFile("文件下载url","目标存储路径","文件名",new FileDownLoadObserver<File>() {
@Override
public void onDownLoadSuccess(File file) {
}
@Override
public void onDownLoadFail(Throwable throwable) {
} @Override
public void onProgress(int progress,long total) {
}
});

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. 具体问题:3、hibernate跟Mybatis/ ibatis 的区别,为什么选择?

    第一章     Hibernate与MyBatis Hibernate 是当前最流行的O/R mapping框架,它出身于sf.net,现在已经成为Jboss的一部分. Mybatis 是另外一种优秀 ...

  2. 树莓派 Learning 002 装机后必要的操作 --- 10 实现本地电脑与远程桌面之间复制粘贴(传输)文件

    树莓派 装机后必要的操作 - 实现本地电脑与远程桌面之间复制粘贴(传输)文件 我的树莓派型号:Raspberry Pi 2 Model B V1.1 装机系统:NOOBS v1.9.2 PC端系统:w ...

  3. CSS学习系列2 -- CSS中的清除浮动

    CSS中有一个很常见的问题,就是元素的浮动. 那么,到底什么是元素的浮动呢,我们来看一个例子 举个例子,在一个div里面内部有浮动元素的话,这个浮动元素会让这个div的高度塌陷. .myDiv{ ba ...

  4. 20169219 linux内核原理与分析第二周作业

    "linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...

  5. SqlDataReader

    using (mycon) { //using语句与try catch finally结合使用 mycon.Open(); // MessageBox.Show("dakai"); ...

  6. SpringBoot第五篇:整合Mybatis

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/10869315.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   ORM框架 ...

  7. JS的几条规则

    总结一下,有这么几条规则需要遵守: 不要使用new Number().new Boolean().new String()创建包装对象: 用parseInt()或parseFloat()来转换任意类型 ...

  8. Java中Class Type 类类型是怎么回事?

    Java中三种方式可以用来表示Class Type(类的实例对象), 第一种,通过隐藏的静态成员变量class来表示:第二种,通过调用该类的对象的getClass方法:第三种,通过Class.forN ...

  9. Codeforces#514D(三分,简单二维几何)

    #include<bits/stdc++.h>using namespace std;const double eps=1e-8;int n; struct node{    double ...

  10. Java——利用集合类实现简单斗地主发牌

    import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util ...