http://www.loongwind.com/archives/290.html
上一篇文章介绍了用Retrofit实现文件的上传与下载,但是我们发现没办法监听上传下载的进度,毕竟我们在做开发的时候经常是要显示上传或者下载的进度了.虽然Retrofit没有给我们提供现成的api来监听进度,但是Retrofit很灵活,它底层网络访问是用的okhttp实现的,当然我们也可以设置其他第三方网络请求库,因为Retrofit可以设置client,我们可以由此来扩展下载上传的进度监听.
本文使用okhttp作为client来做,其实说白了跟用okhttp做下载上传进度监听几乎一样,参考了这篇文章:Android OkHttp文件上传与下载的进度监听扩展
1. 首先我们写两个接口用来下载和上传的进度监听回调:
/**
* 请求体进度回调接口,用于文件上传进度回调
*/
public interface ProgressRequestListener {
void onRequestProgress(long bytesWritten, long contentLength, boolean done);
}
/**
* 响应体进度回调接口,用于文件下载进度回调
*/
public interface ProgressResponseListener {
void onResponseProgress(long bytesRead, long contentLength, boolean done);
}
2. 实现 ProgressRequestBody、ProgressResponseBody
ProgressRequestBody类继承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;
import rx.Observable;
/**
* 包装的请求体,处理进度
*/
public class ProgressRequestBody extends RequestBody {
//实际的待包装请求体
private RequestBody requestBody;
//进度回调接口
private ProgressRequestListener progressListener;
//包装完成的BufferedSink
private BufferedSink bufferedSink;
/**
* 构造函数,赋值
* @param requestBody 待包装的请求体
* @param progressListener 回调接口
*/
public ProgressRequestBody(RequestBody requestBody, ProgressRequestListener progressListener) {
this.requestBody = requestBody;
this.progressListener = progressListener;
}
/**
* 重写调用实际的响应体的contentType
* @return MediaType
*/
@Override
public MediaType contentType() {
return requestBody.contentType();
}
/**
* 重写调用实际的响应体的contentLength
* @return contentLength
* @throws IOException 异常
*/
@Override
public long contentLength() throws IOException {
return requestBody.contentLength();
}
/**
* 重写进行写入
* @param sink BufferedSink
* @throws IOException 异常
*/
@Override
public void writeTo(BufferedSink sink) throws IOException {
if (bufferedSink == null) {
// //包装
bufferedSink = Okio.buffer(sink(sink));
}
//写入
requestBody.writeTo(bufferedSink