Android RxJava2+Retrofit2单文件下载监听进度封装
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单文件下载监听进度封装的更多相关文章
- android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到
android BroadcastReceiver ACTION_TIME_TICK 系统时间监听不到 今天做android上的消息推送,启动了一个独立service,然后在里面监听系统的ACTION ...
- android的Home键的监听封装工具类(一)
android的Home键的监听封装: package com.gzcivil.utils; import android.content.BroadcastReceiver; import andr ...
- [Android] Android RxJava2+Retrofit2+OkHttp3 的使用(一) --基础篇 Retrofit2 的使用
本文是 Android RxJava2+Retrofit2+OkHttp3 的使用(一) --基础篇 Retrofit2 的使用 本文的目标是用 Retrofit写一个网络请求: 本文以从获取天气预报 ...
- [Android] Android RxJava2+Retrofit2+OkHttp3 的使用
[Android] Android RxJava2+Retrofit2+OkHttp3 简单介绍Retrofit.OKHttp和RxJava之间的关系: Retrofit:Retrofit是Squar ...
- 使用NSURLSessionDownloadTask实现大文件下载-监听下载进度
- 5.1 涉及知识点(1)创建NSURLSession并设置代理,通过NSURLSessionDownloadTask并以代理的方式来完成大文件的下载 //1.创建NSURLSession,设置代理 ...
- 【Android代码片段之八】监听Android屏幕是否锁屏
实现方法:1)通过BroadcastReceiver接收广播Intent.ACTION_SCREEN_ON和Intent.ACTION_SCREEN_OFF可以判断屏幕状态是否锁屏,但是只有屏幕状态发 ...
- Android Edittext 显示光标 获取焦点 监听焦点
Edittext java 代码控制获取焦点 EditText mEditText = (EditText) findViewById(R.id.et); mEditText.setFocusable ...
- android 呼入电话的监听(来电监听)转
需要权限: <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 方式一:通过广 ...
- 另辟思路解决 Android 4.0.4 不能监听Home键的问题
问题描述: 自从Android 4.0以后,开发人员是不能监听和屏蔽Home键的,对于KEYCODE_HOME,官方给出的描述如下: Home key. This key is handled by ...
随机推荐
- R语言 arules包 apriori()函数中文帮助文档(中英文对照)
apriori(arules) apriori()所属R语言包:arules Mining Associations w ...
- 一个web.Config或app.Config自定义段configSections的示例--转
直接用配置文件app.Config或web.Config配置应用系统的运行参数,比自己做一个xml配置文件,简洁方便得多.这两个配置文件不仅有常见的connectionStrings和appSetti ...
- pure css简单组件,借鉴bootstrap
<!doctype html> <html> <head> <meta http-equiv="Content-type" content ...
- 线程池和Thread
1.线程池 创建线程需要时间.如果有不同的短任务要完成,就可以事先创建许多线程,在应完成这些任务时发出请求.这个线程数最好在需要更多线程时增加,在需要释放资源时减少.不需要自己创建这样一个列表.该列表 ...
- Dapper 增删改查
0.数据库及实体类 create table Users ( Id ,) primary key, Name nvarchar() not null, Password nvarchar() not ...
- Yahoo Progamming Contest 2019D(DP,思维)
#include<bits/stdc++.h>using namespace std;long long n,v,a,b,c,d,e;int main(){ scanf(" ...
- 清北刷题冲刺 11-02 a.m
卖书 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...
- 避免picture图片无法删除,提示正在被其他进程使用
pictureBox1.Image = Image.FromStream(ByteToStream(SetImageToByteArray(cutImgPath))); #region 将文件转换成流 ...
- NYOJ542-试制品
题目链接:点击打开链接 试 制 品 时间限制:1000 ms | 内存限制:65535 KB 难度: 描述 ZZ大学的Dr.Kong最近发现实验室的很多试制品都已经用完.由于项目经费有限,为了节省 ...
- 微信小程序通过JS动态修改页面标题setNavigationBarTitle
wx.setNavigationBarTitle({title: '当前页面'})