Android RxJava2+Retrofit2单文件下载监听进度封装

当筵意气临九霄,星离雨散不终朝。这篇文章主要讲述Android RxJava2+Retrofit2单文件下载监听进度封装相关的知识,希望能为你提供帮助。
Rxjava2和Retrofit2用的越来越多,最近也在封装一个通用的网络请求库,其中就包括了单文件下载的方法,所以这里进行记录。文末附带Demo
由于网上很多的方法都是使用拦截器进行进度的监听,个人觉得使用起来非常复杂和,所以取了个巧,在文件写入到硬盘的时候对文件读写进行监听,就解决了retrofit2下载文件没有进度监听的问题。
先上封装之后的使用代码,使用简单,直接回调下载之后的文件【Android RxJava2+Retrofit2单文件下载监听进度封装】

Android RxJava2+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) { } });

  • 项目Demo地址

    推荐阅读