Android RxJava2+Retrofit2单文件下载监听进度封装
Posted 星辰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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[2048]; int len = 0; FileOutputStream fos = null; try { is = responseBody.byteStream(); final long total = responseBody.contentLength(); long sum = 0; 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)) != -1) { sum += len; fos.write(buf, 0, len); final long finalSum = sum; //这里就是对进度的监听回调 onProgress((int) (finalSum * 100 / 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单文件下载监听进度封装的主要内容,如果未能解决你的问题,请参考以下文章
基于RxJava2+Retrofit2精心打造的Android基础框架XSnow
基于RxJava2+Retrofit2精心打造的Android基础框架XSnow