retrofit显示上传文件进度

来源:互联网 发布:克而瑞数据 编辑:程序博客网 时间:2024/05/21 21:46

  首先说一下,如果是使用了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;    }    @Override    public MediaType contentType() {        return requestBody.contentType();    }    @Override    public 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();//    }    @Override    public 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()方法            @Override            public 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);    }

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