0
点赞
收藏
分享

微信扫一扫

Retrofit下载文件实时进度显示

奔跑的酆 2022-02-18 阅读 52
p2plinqgnu

1.进度接口

public interface ProgressListener {
        void update(String url, long bytesRead, long contentLength, boolean done);
    }

2.重写ResponeBody

 public class ProgressResponseBody extends ResponseBody {

        private final ResponseBody responseBody;
        private final ProgressListener progressListener;
        private BufferedSource bufferedSource;
        private final String url;

        ProgressResponseBody(String url, ResponseBody responseBody, ProgressListener progressListener) {
            this.responseBody = responseBody;
            this.progressListener = progressListener;
            this.url = url;
        }

        @Override
        public MediaType contentType() {
            return responseBody.contentType();
        }

        @Override
        public long contentLength() {
            return responseBody.contentLength();
        }

        @Override
        public BufferedSource source() {
            if (bufferedSource == null) {
                bufferedSource = Okio.buffer(source(responseBody.source()));
            }
            return bufferedSource;
        }

        private Source source(final Source source) {
            return new ForwardingSource(source) {
                long totalBytesRead = 0L;

                @Override
                public long read(Buffer sink, long byteCount) throws IOException {
                    long bytesRead = super.read(sink, byteCount);
                    // read() returns the number of bytes read, or -1 if this source is exhausted.
                    totalBytesRead += bytesRead != -1 ? bytesRead : 0;
                    progressListener.update(url, totalBytesRead, responseBody.contentLength(), bytesRead == -1);
                    return bytesRead;
                }
            };
        }
    }

 3.重写拦截器

public class ProgressInterceptor implements Interceptor {

        private ProgressListener progressListener;

        public ProgressInterceptor(ProgressListener progressListener) {
            this.progressListener = progressListener;
        }

        @NotNull
        @Override
        public Response intercept(@NotNull Chain chain) throws IOException {
            Response originalResponse = chain.proceed(chain.request());
            return originalResponse.newBuilder()
                    .body(new ProgressResponseBody(chain.request().url().url().toString(), originalResponse.body(), progressListener))
                    .build();
        }
    }

4.构建OkHttpClient时添加NetworkInterceptor

 okHttpClient = new OkHttpClient.Builder()
                .addNetworkInterceptor(new ProgressInterceptor(new ProgressListener() {
                    @Override
                    public void update(String url, long bytesRead, long contentLength,
                                       boolean done) {
                          //这里处理进度
                    }
                }))
                ....

这个拦截器是在onNext之前生效的,会在文件全部下载完成后调用onNext,然后获取一下输入流写入文件就好了。

5.一些问题

       1.下载个王者荣耀OOM了(已经添加@Streaming),查了一下说是Interceptor.setLevel()不要设置Body,还没测试。

        2.observeOn()在主线程时,UI刷新不了。没搞懂

举报

相关推荐

0 条评论