package com.cheng.networkframestudy.okhttp.frame.request; 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; /** * Decorates an OkHttp request body to count the number of bytes written when writing it. Can * decorate any request body, but is most useful for tracking the upload progress of large * multipart requests. * * @author Leo Nikkil? */ public class CountingRequestBody extends RequestBody { protected RequestBody mDelegate; protected Listener mListener; protected CountingSink mCountingSink; public CountingRequestBody(RequestBody delegate, Listener listener) { this.mDelegate = delegate; this.mListener = listener; } @Override public MediaType contentType() { return mDelegate.contentType(); } @Override public long contentLength() { try { return mDelegate.contentLength(); } catch (IOException e) { e.printStackTrace(); } return -1; } @Override public void writeTo(BufferedSink sink) throws IOException { mCountingSink = new CountingSink(sink); BufferedSink bufferedSink = Okio.buffer(mCountingSink); mDelegate.writeTo(bufferedSink); bufferedSink.flush(); } protected final class CountingSink extends ForwardingSink { private long bytesWritten = 0; public CountingSink(Sink delegate) { super(delegate); } @Override public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); bytesWritten += byteCount; mListener.onRequestProgress(bytesWritten, contentLength()); } } public static interface Listener { public void onRequestProgress(long bytesWritten, long contentLength); } }