zoukankan      html  css  js  c++  java
  • 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) {
                                }
                            });
  • 相关阅读:
    Python Data Analysis Library¶
    matadon/mizuno
    MySQL 5.1参考手册
    Apache Derby: Quick Start
    JRuby大捷:ThoughtWorks宣布Mingle发布在即
    RailsWithH2InJNDIOnJetty
    Embedded Jetty and Spring: The Lightweight Antidote for Java EE Complexity
    window下安装解压缩版mysql/zip压缩文件包非install安装程序
    Chapter 9. Extending Workbench
    Mysql手动增加一列_Blog of Grow_百度空间
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/9256908.html
Copyright © 2011-2022 走看看