• 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) {
                                }
                            });
  • 相关阅读:
    Atitit  atiMail atiDns新特性 v2  q39
    Atitit  atiMail atiDns新特性 v2  q39
    Atitit.aticmd v4  新特性q39 添加定时器释放功能
    Atitit.aticmd v4  新特性q39 添加定时器释放功能
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit.编程语言and 自然语言的比较and 编程语言未来的发展
    Atitit.编程语言and 自然语言的比较and 编程语言未来的发展
    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31
    知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31无涯 - I
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/9256908.html
Copyright © 2020-2023  润新知