不要在最需要奋斗的年纪选择了安逸!
在上一讲中Retrofit(一)、Retrofit+OkHttp实现简单的Get与Post请求 中实现了用Retrofit实现简单的Get与post请求。下面我们用Retrofit实现文件下载与上传并带进度!可以参考这两篇博文:
OkHttp下载文件并带进度条
OkHttp上传文件到服务器并带进度
一、文件的下载
1.写下载接口
public interface DownloadRetrofit{
@GET("download/2.jpg")
Call<ResponseBody> downloadFile();
}
2.在RetrofitUtil类中增加一个下载的方法downloadFileProgress
public static String baseUrl = "http://192.168.0.100:8080/OkHttpServer/";
public static Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
// .addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl);
private static OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10000, TimeUnit.MILLISECONDS)
.readTimeout(10000,TimeUnit.MILLISECONDS)
.writeTimeout(10000,TimeUnit.MILLISECONDS).build();
public static void downloadFileProgress( final ProgressListener listener,Callback<ResponseBody> callback){
//okhttp拦截
OkHttpClient client = okHttpClient.newBuilder().addNetworkInterceptor(new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Response response = chain.proceed(chain.request());
return response.newBuilder().body(new ProgressResponseBody(response.body(),listener)).build();
}
}).build();
InterfaceRetrofit.DownloadRetrofit downloadRetrofit = retrofitBuilder.client(client).build().create(InterfaceRetrofit.DownloadRetrofit.class);
downloadRetrofit.downloadFile().enqueue(callback);
}
上面代码中ProgressResponseBody代码如下:
public class ProgressResponseBody extends ResponseBody {
public static final int UPDATE = 0x01;
public static final String TAG = ProgressResponseBody.class.getName();
private ResponseBody responseBody;
private ProgressListener mListener;
private BufferedSource bufferedSource;
private Handler myHandler;
public ProgressResponseBody(ResponseBody body, ProgressListener listener) {
responseBody = body;
mListener = listener;
if (myHandler==null){
myHandler = new MyHandler();
}
}
class MyHandler extends Handler {
public MyHandler() {
super(Looper.getMainLooper());
}
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case UPDATE:
ProgressModel progressModel = (ProgressModel) msg.obj;
if (mListener!=null)mListener.onProgress(progressModel.getCurrentBytes(),progressModel.getContentLength(),progressModel.isDone());
break;
}
}
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource==null){
bufferedSource = Okio.buffer(mySource(responseBody.source()));
}
return bufferedSource;
}
private Source mySource(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);
totalBytesRead +=bytesRead!=-1?bytesRead:0;
Message msg = Message.obtain();
msg.what = UPDATE;
msg.obj = new ProgressModel(totalBytesRead,contentLength(),totalBytesRead==contentLength());
myHandler.sendMessage(msg);
Log.i(TAG,"currentBytes=="+totalBytesRead+"==contentLength=="+contentLength());
return bytesRead;
}
};
}
}
3.另外进度接口:
public interface ProgressListener {
void onProgress(long currentBytes, long contentLength, boolean done);
}
ProgressModel实体类:
public class ProgressModel implements Parcelable {
private long currentBytes;
private long contentLength;
private boolean done = false;
public ProgressModel(long currentBytes, long contentLength, boolean done) {
this.currentBytes = currentBytes;
this.contentLength = contentLength;
this.done = done;
}
public long getCurrentBytes() {
return currentBytes;
}
public void setCurrentBytes(long currentBytes) {
this.currentBytes = currentBytes;
}
public long getContentLength() {
return contentLength;
}
public void setContentLength(long contentLength) {
this.contentLength = contentLength;
}
public boolean isDone() {
return done;
}
public void setDone(boolean done) {
this.done = done;
}
private static final Creator<ProgressModel> CREATOR = new Creator<ProgressModel>() {
@Override
public ProgressModel createFromParcel(Parcel parcel) {
return new ProgressModel(parcel);
}
@Override
public ProgressModel[] newArray(int i) {
return new ProgressModel[i];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeLong(currentBytes);
parcel.writeLong(contentLength);
parcel.writeByte((byte) (done==true?1:0));
}
protected ProgressModel(Parcel parcel) {
currentBytes = parcel.readLong();
contentLength = parcel.readLong();
done = parcel.readByte()!=0;
}
}