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. 菜鸟大充电啦啦啦啦啦:eclipse SDK 是什么啊

    为什么下载是,没有单独的ecipse呢,,总是eclipse-sdk呢 而且还很大几百兆 回复1: Eclipse有好多专用名称,例如Eclipse SDK等.先说一下SDK, Eclipse Pro ...

  2. linux中制作动态库

    制作一个动态库我们可以使用gcc工具来制作一个动态库示例:自己制作一个动态库,库函数的功能是传递一个字符串并输出.第一步:需要准备3个文件:hello.h.hello.c.test.c.其中hello ...

  3. 阶段3-团队合作\项目-网络安全传输系统\sprint1-传输子系统设计\第3课-加密传输优化

    对之前的传输系统进行加密,使之成为加密的网络传输系统 客户端编程模型 通过以上模型对传统的TCP传输模型进行优化 首先完成初始化工作,它是要在创建socket之前完成 主要是以上四个函数的实现,那么这 ...

  4. Citrix 虚拟化 最小化后无法最大化

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Citrix\wfshell\TWI\创建DWORD类型键值:SeamlessFlags    ...

  5. 图像标注工具labelImg使用方法

    最近在做打标签的工作,为了与大家参考学习,总结了在windows的环境下,基于anaconda的图像标注工具labellmg的一种使用方法! 1 搭建anaconda 以前写过怎么搭建anaconda ...

  6. SAS笔记(5) FLAG和计数器

    考虑这样一种场景:我们有一份患者入院检查的数据,我们知道一个患者有可能会多次去医院做检查,每次检查的结果可能为阳性,也可能为阴性.我们现在关注的是某一个患者在若干次检查中是否出现了阳性结果,在R中我们 ...

  7. 分层图最短路【bzoj2662】[BeiJing wc2012]冻结

    分层图最短路[bzoj2662][BeiJing wc2012]冻结 Description "我要成为魔法少女!" "那么,以灵魂为代价,你希望得到什么?" ...

  8. Windows平台Anaconda使用笔记

    1.官网下载anaconda安装. 2.将命令行工具路径加入系统环境变量 C:\ProgramData\Anaconda3\ScriptsC:\ProgramData\Anaconda3\Librar ...

  9. Proxy opening connection toSpringClound配置豪猪hystrixDashboard发生

    Proxy opening connection to: http://localhost:8001/hystrix.stream 配置hystrixDashboard发生的错误.一直在寻找 最后发现 ...

  10. @Modifying 注解完成修改操作

    以上我们做的都是查询,那要如何实现 修改.删除和添加呢? 可以通过以下两种方式: (1)通过实现 CrudRepository 接口来完成(以后介绍): (2)通过 @Modifying 注解完成修改 ...