下载进度的在之前的文章中实现过:
Android的Splash启动图的两种动态切换方式
根据服务器的数据声明上传文件的方法
@Multipart
@POST("upload")
Observable<UploadImgBean> uploadHeadPic(@Part MultipartBody.Part files);
借助okhttp的RequestBody
我们构造一个FileRequestBody
继承RequestBody
public class FileRequestBody extends RequestBody {
private RequestBody mRequestBody;
private LoadingListener mLoadingListener;
private long mContentLength;
public FileRequestBody(RequestBody requestBody, LoadingListener loadingListener) {
mRequestBody = requestBody;
mLoadingListener = loadingListener;
}
//文件的总长度
@Override
public long contentLength() {
try {
if (mContentLength == 0)
mContentLength = mRequestBody.contentLength();
return mContentLength;
} catch (IOException e) {
e.printStackTrace();
}
return -1;
}
@Override
public MediaType contentType() {
return mRequestBody.contentType();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
ByteSink byteSink = new ByteSink(sink);
BufferedSink mBufferedSink = Okio.buffer(byteSink);
mRequestBody.writeTo(mBufferedSink);
mBufferedSink.flush();
}
private final class ByteSink extends ForwardingSink {
//已经上传的长度
private long mByteLength = 0L;
ByteSink(Sink delegate) {
super(delegate);
}
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
mByteLength += byteCount;
mLoadingListener.onProgress(mByteLength, contentLength());
}
}
public interface LoadingListener {
void onProgress(long currentLength, long contentLength);
}
}
实现上传
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
FileRequestBody fileRequestBody = new FileRequestBody(requestFile, new FileRequestBody.LoadingListener() {
@Override
public void onProgress(long currentLength, long contentLength) {
//获取上传的比例
Log.d("Tag---", currentLength + "/" + contentLength);
}
});
//files是与服务器对应的key
MultipartBody.Part body =
MultipartBody.Part.createFormData("files", file.getName(), fileRequestBody);
RetrofitHelper.userApi().uploadHeadPic(body).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<UploadImgBean>() {
@Override
public void call(UploadImgBean uploadImgBean) {
//上传成功
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
//上传失败
}
});