package licola.demo.com.huabandemo.HttpUtils; import java.io.IOException; import licola.demo.com.huabandemo.API.OnProgressResponseListener; import okhttp3.MediaType; import okhttp3.ResponseBody; import okio.Buffer; import okio.BufferedSource; import okio.ForwardingSource; import okio.Okio; import okio.Source; /** * Created by LiCola on 2016/05/12 15:37 * ResponseBody响应体的包装类 * 主要功能是添加接口回调进度 * 方法来自 https://github.com/square/okhttp/blob/master/samples%2Fguide%2Fsrc%2Fmain%2Fjava%2Fokhttp3%2Frecipes%2FProgress.java */ public class ProgressResponseBody extends ResponseBody { private static final String TAG = "ProgressResponseBody"; //实际的待包装响应体 private final ResponseBody responseBody; //进度回调接口 private final OnProgressResponseListener progressListener; //包装完成的BufferedSource private BufferedSource bufferedSource; /** * 构造函数 依赖注入 * * @param responseBody 待包装的响应体 * @param progressListener 回调接口 */ public ProgressResponseBody(ResponseBody responseBody, OnProgressResponseListener progressListener) { this.responseBody = responseBody; this.progressListener = progressListener; } /** * 重写调用实际的响应体的contentType * * @return MediaType */ @Override public MediaType contentType() { return responseBody.contentType(); } /** * 重写调用实际的响应体的contentLength * * @return contentLength * @throws IOException 异常 */ @Override public long contentLength() { return responseBody.contentLength(); } /** * 重写进行包装source * * @return BufferedSource * @throws IOException 异常 */ @Override public BufferedSource source() { if (bufferedSource == null) { bufferedSource = Okio.buffer(source(responseBody.source())); } return bufferedSource; } private Source source(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.onResponseProgress(totalBytesRead, responseBody.contentLength(), bytesRead == -1); return bytesRead; } }; } }