首先说一下,如果是使用了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);}
我上面的类里面有注释,,其实是一样的代码,,,我懒得删掉。