当前位置: 代码迷 >> 综合 >> retrofit显示上传文件进度
  详细解决方案

retrofit显示上传文件进度

热度:44   发布时间:2023-10-15 10:13:10.0

  首先说一下,如果是使用了Interceptor来拦截请求log的话,会导致上传两遍,而导致上传失败,会抱一个protcolException,unexpected of Stream,那么你要是上传的话就注释掉日志就可以了。

  其实这个东西的重点是写一个集成RequestBody的类就可以了,网上一大堆大同小异:

import java.io.IOException;import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import okio.BufferedSink;
import okio.ForwardingSink;
import okio.Okio;
import okio.Sink;/*** Created by Administrator on 2017/5/24 0024.*/public class CountingRequestBody extends RequestBody {protected RequestBody requestBody;private UploadListener listener;
//    private CountingSink countingSink;private BufferedSink bufferedSink;public CountingRequestBody(RequestBody requestBody, UploadListener listener) {this.requestBody = requestBody;this.listener = listener;}@Overridepublic MediaType contentType() {return requestBody.contentType();}@Overridepublic long contentLength() throws IOException {return requestBody.contentLength();}//    @Override
//    public void writeTo(BufferedSink sink) throws IOException {
//        countingSink = new CountingSink(sink);
//        if (bufferedSink == null)
//            bufferedSink = Okio.buffer(countingSink);
//        requestBody.writeTo(bufferedSink);
//        bufferedSink.flush();
//    }@Overridepublic void writeTo(BufferedSink sink) throws IOException {
//        countingSink = new CountingSink(sink);if (bufferedSink == null)bufferedSink = Okio.buffer(sink(sink));//写入requestBody.writeTo(bufferedSink);//必须调bubufferedSink.flush();不然最后一部分数据可能不会被写入bufferedSink.flush();}private Sink sink(Sink sink) {return new ForwardingSink(sink) {long byteWritten = 0L;//当前写入字节数long contentLength = 0L;//总字节长度,避免多次调用contentLength()方法@Overridepublic void write(Buffer source, long byteCount) throws IOException {super.write(source, byteCount);if (contentLength == 0)contentLength = contentLength();//获取总字节长度,避免多次调用byteWritten += byteCount;//累计当前写入字节数if (listener != null)listener.onRequestProgress(byteWritten, contentLength,byteWritten == contentLength);}};}//    protected final class CountingSink extends ForwardingSink {
//        long byteWriten = 0L;
//        Long contentLength = 0L;
//
//        public CountingSink(Sink delegate) {
//            super(delegate);
//        }
//
//        @Override
//        public void write(Buffer source, long byteCount) throws IOException {
//            super.write(source, byteCount);
//            byteWriten += byteCount;
//            if (contentLength == 0)
//                contentLength = contentLength();
//            listener.onRequestProgress(byteWriten, contentLength);
//        }
//    }public interface UploadListener {void onRequestProgress(long byteWrited, long contentLength,boolean done);}

我上面的类里面有注释,,其实是一样的代码,,,我懒得删掉。