自定义了RequestBody,我点击上传,会出现这种情况: progressbar会走完一次,然后再从零开始正常走.想要实现的是,点击上传,正常从零开始走.
下面是上传的代码函数和自定义RequstBody
1.上传类的函数:
/**
* 上传视频
*/
private void uploadVideo() {
String title = mTitle.getText().toString().trim();
if (TextUtils.isEmpty(title)) {
ToastUtil.showMessage(R.string.title_cannot_empty);
return;
}
HashMap<String, String> map = new HashMap<>();
File file = new File(url);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
//无进度
// MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
//自定义RequestBody显示进度
MyBody myBody = new MyBody(requestBody, new MyBody.ProgressListener() {
@Override
public void onProgress(long currentBytes, long contentLength) {
int current = new Long(currentBytes).intValue();
int total = new Long(contentLength).intValue();
if (seted) {
numberProgressBar.setVisibility(View.VISIBLE);
numberProgressBar.setMax(total); //只设置一次最大值
seted = false;
Log.d(TAG, "onProgress: 1040 "+ total);
}
numberProgressBar.setProgress(current);
}
});
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), myBody);
String uid = UserManager.getInstance().getUid();
map.put("type", "user");
map.put("dataType", "1");
map.put("videoType", "video");
map.put("dataName", title);
map.put("userId", uid);
RxManager.getMethod().uploadVideo(body, map)
.compose(RxUtil.schedulers(this))
.subscribe(new RxCallback<UploadVideoBean>(this) {
@Override
public void onSuccess(UploadVideoBean uploadVideoBean, String msg) {
ToastUtil.showMessage(R.string.upload_success_please_wait_audit, 4000);
MainActivity.open(PreviewActivity.this);
finish();
}
});
}
2.自定义RequstBody:
public class MyBody extends RequestBody {
private static final String TAG = "MyBody";
public interface ProgressListener {
void onProgress(long currentBytes, long contentLength);
}
public class ProgressModel {
private long currentBytes = 0;
private long contentLength = 0;
public ProgressModel(long currentBytes, long contentLength) {
this.currentBytes = currentBytes;
this.contentLength = contentLength;
}
public long getCurrentBytes() {
return currentBytes;
}
public long getContentLength() {
return contentLength;
}
}
public static final int UPDATE = 0x01;
private RequestBody requestBody;
private ProgressListener mListener;
private MyHandler myHandler;
private BufferedSink bufferedSink;
public MyBody(RequestBody body, ProgressListener listener) {
requestBody = 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());
break;
}
}
}
@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 (bufferedSink == null) {
bufferedSink = Okio.buffer(sink(sink));
// }
//TODO:最初写法,这样会无法上传,注释掉空判断
// if (bufferedSink == null) {
// bufferedSink = Okio.buffer(sink(sink));
// }
//写入
requestBody.writeTo(bufferedSink);
//刷新
bufferedSink.flush();
}
private Sink sink(BufferedSink sink) {
return new ForwardingSink(sink) {
long bytesWritten = 0L;
long contentLength = 0L;
@Override
public void write(Buffer source, long byteCount) throws IOException {
super.write(source, byteCount);
if (contentLength == 0) {
contentLength = contentLength();
}
bytesWritten += byteCount;
//走了两次
Log.d(TAG, "write: 1029= bytesWritten: "+bytesWritten+" ,contenglenth:"+contentLength);
Message msg = Message.obtain(); //回调
msg.what = UPDATE;
msg.obj = new ProgressModel(bytesWritten, contentLength);
myHandler.sendMessage(msg);
}
};
}
}
因为项目中重写了LoggingInterceptor 类。而这个类也调用了 RequestBody的write方法.只要判断BufferedSink为Buffer类型才上传数据就行了