1.写一个上传监听的接口:
/**
* Created by Zzm丶Fiona on 2017/7/31.
*/
public interface RetrofitProgressUploadListener {
/**
*
* @param bytesWriting 已经写的字节数
* @param totalBytes 文件的总字节数
*/
void onProgress(long bytesWriting, long totalBytes);
}
2.重新写一个类继承于RequesBody:
package zzm.zzmotherthingsshouldknowfortheinterview.upload_progress; import android.support.annotation.Nullable; 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; /** * Created by Zzm丶Fiona on 2017/7/31. */ public class ProgressRequestBody extends RequestBody { private final RetrofitProgressUploadListener retrofitProgressUploadListener; private final RequestBody requestBody; private BufferedSink bufferedSink; public ProgressRequestBody(RetrofitProgressUploadListener retrofitProgressUploadListener, RequestBody requestBody) { this.retrofitProgressUploadListener = retrofitProgressUploadListener; this.requestBody = requestBody; } @Nullable @Override public MediaType contentType() { return requestBody.contentType(); } @Override public long contentLength() throws IOException { return requestBody.contentLength(); } //关键方法 @Override public void writeTo(BufferedSink sink) throws IOException { if (null == bufferedSink) bufferedSink = Okio.buffer(sink(sink)); requestBody.writeTo(bufferedSink); //必须调用flush,否则最后一部分数据可能不会被写入 bufferedSink.flush(); } private Sink sink(Sink sink) { return new ForwardingSink(sink) { long bytesWriting = 0l; long contentLength = 0l; @Override public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); if (0 == contentLength) contentLength = contentLength(); bytesWriting += byteCount; //调用接口,把上传文件的进度传过去 retrofitProgressUploadListener.onProgress(bytesWriting, contentLength); } }; } }
3.封装的方法,返回ProgressRequestBody:
package zzm.zzmotherthingsshouldknowfortheinterview.utils;
import android.os.Handler;
import okhttp3.RequestBody;
import zzm.zzmotherthingsshouldknowfortheinterview.upload_progress.ProgressRequestBody;
import zzm.zzmotherthingsshouldknowfortheinterview.upload_progress.RetrofitProgressUploadListener;
import zzm.zzmotherthingsshouldknowfortheinterview.upload_progress.UploadProgressBean;
/**
* Created by Zzm丶Fiona on 2017/7/31.
*/
public class RetrofitUploadProgressUtil {
//handler把数据传送到主线程中去处理,展示
public static ProgressRequestBody getProgressRequesBody(RequestBody requestBody, final Handler handler) {
return new ProgressRequestBody(new RetrofitProgressUploadListener() {
UploadProgressBean uploadProgressBean = new UploadProgressBean();
@Override
public void onProgress(long bytesWriting, long totalBytes) {
if (null == uploadProgressBean) uploadProgressBean = new UploadProgressBean();
uploadProgressBean.setBytesWriting(bytesWriting);
uploadProgressBean.setTotalBytes(totalBytes);
handler.sendMessage(handler.obtainMessage(2, uploadProgressBean));
}
}, requestBody);
}
}
4.把自己的写的类继承于RequesBody的ProgressRequestBody传进上传的表单中即可:
/** * Created by Zzm丶Fiona on 2017/7/30. */ public class UploadThingsByRetrofitActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),你的上传文件-file); ProgressRequestBody progressRequestBody = RetrofitUploadProgressUtil.getProgressRequesBody(requestBody, new Handler() { @Override public void handleMessage(Message msg) { //进度的展示: super.handleMessage(msg); Log.i("zzmzzm", "已读的字节数: " + ((UploadProgressBean) msg.obj).getTotalBytes()); Log.i("zzmzzm", "上传的文件的字节总数: " + ((UploadProgressBean) msg.obj).getTotalBytes()); } }); UploadThingsByRetrofitInterface uploadThingsByRetrofitInterface = getUploadThingsInterface(); Call<ResponseBody> upload = uploadThingsByRetrofitInterface.uploadThings(MultipartBody.Part.createFormData(你的key,文件名,progressRequestBody)); upload.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { //求情成功的返回 try { Log.i("zzmzzm", response.body().string()); } catch (IOException e) { Log.i("zzmzzm", e.toString()); } } //求情失败的返回 @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.i("zzmzzm", t.toString()); } }); } private UploadThingsByRetrofitInterface getUploadThingsInterface() { return new Retrofit.Builder() .baseUrl("地址") .build() .create(UploadThingsByRetrofitInterface.class); } }
其中的注解接口:
/** * Created by Zzm丶Fiona on 2017/7/30. */ public interface UploadThingsByRetrofitInterface { @Multipart @POST Call<ResponseBody> uploadThings(@Part MultipartBody.Part uplodThings); }
补充说明:
MediaType.parse(String contentType)中参数contentType常见的有: text/html : HTML格式 text/plain :纯文本格式 text/xml : XML格式 text/x-markdown: markdown文档 image/gif :gif图片格式 image/jpeg :jpg图片格式 image/png:png图片格式 以application开头的媒体格式类型: application/xhtml+xml :XHTML格式 application/xml : XML数据格式 application/atom+xml :Atom XML聚合格式 application/json : JSON数据格式 application/pdf :pdf格式 application/msword : Word文档格式 application/octet-stream : 二进制流数据(如常见的文件下载) application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式) 另外一种常见的媒体格式是上传文件之时使用的: multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式 另外的可以参考:http://www.w3school.com.cn/media/media_mimeref.asp
转载于:https://my.oschina.net/u/2987490/blog/1492353