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);