com.cmonbaby.http.stream.upload.UploadFiles Maven / Gradle / Ivy
Show all versions of http_lower Show documentation
package com.cmonbaby.http.stream.upload;
import android.text.TextUtils;
import android.util.Log;
import com.cmonbaby.http.core.HttpCallback;
import com.cmonbaby.http.dialog.FileLoadable;
import com.cmonbaby.http.schedulers.AndroidSchedulers;
import com.cmonbaby.http.stream.listener.ProgressListener;
import com.cmonbaby.http.utils.RetrofitUtils;
import java.io.File;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
/**
* Author: Simon
*
QO: 8950764
*
Email: [email protected]
*
WebSize: https://www.cmonbaby.com
*
Version: 1.0.0
*
Date: 2020/12/28
*
Description: 上传多个文件
*/
public class UploadFiles {
private Observable observable; // 从retrofit返回的Observable。被观察者
private final Class clazz; // Retrofit接口Class
private final ProgressListener progressListener; // 上传进度监听
private final Action0 before; // http请求开始的时候一些界面上的处理
private final Action1 filter; // http请求完成时过滤,比如isSuccess = false,调用onError()
private final FileLoadable loadable; // 对于activity和fragment loading的处理
private String dialogTitle; // loading标题
private String dialogContent; // loading内容摘要
private final UploadFilesCall requestService; // 上传多文件时,将RequestBody组装Observable
private final HttpCallback callback; // Http请求回调
private final Map requestBodyMap;
private UploadFiles(Builder builder) {
this.observable = builder.observable;
this.clazz = builder.clazz;
this.progressListener = builder.progressListener;
this.before = builder.before;
this.filter = builder.filter;
this.loadable = builder.loadable;
this.dialogTitle = builder.dialogTitle;
this.dialogContent = builder.dialogContent;
this.requestService = builder.requestService;
this.callback = builder.callback;
this.requestBodyMap = builder.requestBodyMap;
}
private Subscription startUpload() {
if (callback == null) {
Log.e("初始化callback错误", "请实现:callback(new HttpCallback())方法");
return null;
}
if (requestBodyMap == null || requestBodyMap.size() == 0) return null;
if (TextUtils.isEmpty(dialogTitle)) dialogTitle = "文件上传";
if (TextUtils.isEmpty(dialogContent)) dialogContent = "文件上传中,请稍候……";
Observer httpCallback = new Observer() {
@Override
public void onCompleted() {
if (loadable != null) loadable.dismissFileDialog();
}
@Override
public void onError(Throwable e) {
if (loadable != null) loadable.dismissFileDialog();
callback.onError(e);
}
@Override
public void onNext(T t) {
callback.onSuccessful(t);
}
};
S s = RetrofitUtils.getInstance().createRequestService(clazz, (progress, total, isFinish) -> {
if (progressListener != null) progressListener.onProgress(progress, total, isFinish);
if (loadable != null && total > 0 && progress > 0) {
int pro = new BigDecimal((progress / 1024)).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
loadable.setDialogMaxProgress((int) (total / 1024));
loadable.setDialogProgress(pro);
}
});
if (requestService == null) {
Log.e("初始化requestService错误", "请实现:requestService(new UploadFilesCall())方法");
return null;
}
observable = requestService.uploadFiles(s, requestBodyMap);
if (observable == null) {
Log.e("初始化observable错误", "请检查实现:requestService(new UploadFilesCall())方法");
return null;
}
return observable.subscribeOn(Schedulers.io()) // 是http请求的操作是在io线程中调用,而不是UI线程中。
.observeOn(AndroidSchedulers.mainThread()) // 确保subscriber的回调,即onNext、onError和onCompleted是在Ui线程中回调
.doOnSubscribe(() -> {
if (loadable != null) loadable.showProgressDialog(); // 如果不为空,就进行loading的show操作
if (loadable != null) loadable.setFileDialogTitle(dialogTitle);
if (loadable != null) loadable.setFileDialogContent(dialogContent);
if (before != null) before.call(); // 进行额外的界面处理,在http请求开始的时候
}) // http请求开始时,一些初始化的操作。比如loading界面的显示
.subscribeOn(AndroidSchedulers.mainThread()) // 这里切换到UI线程,确保doOnSubscribe在UI线程中进行,以便subscribe回调是在UI线程中进行。
.doOnNext(t -> { // 处理
if (filter != null) filter.call(t); // 进行额外的界面处理,在http请求开始的时候
})
.subscribe(httpCallback);
}
public static final class Builder {
private final Observable observable; // 从retrofit返回的Observable。被观察者
private final Class clazz; // Retrofit接口Class
private ProgressListener progressListener; // 上传进度监听
private Action0 before; // http请求开始的时候一些界面上的处理
private Action1 filter; // http请求完成时过滤,比如isSuccess = false,调用onError()
private FileLoadable loadable; // 对于activity和fragment loading的处理
private String dialogTitle; // loading标题
private String dialogContent; // loading内容摘要
private UploadFilesCall requestService; // 上传多文件时,将RequestBody组装Observable
private HttpCallback callback; // Http请求回调
private final Map requestBodyMap;
private String fileParams; // 上传文件参数名
private Builder(Class clazz, Observable observable) {
this.clazz = clazz;
this.observable = observable;
this.requestBodyMap = new HashMap<>();
}
public static Builder uploadFiles(Class clazz, Observable observable) {
return new Builder<>(clazz, observable);
}
public Builder files(File file) {
if (file != null && file.exists()) {
RequestBody requestBody = RequestBody.create(MediaType.parse("multiple/form-data"), file);
if (TextUtils.isEmpty(fileParams)) fileParams = "files";
requestBodyMap.put(fileParams + "\"; filename=\"" + file.getName(), requestBody);
}
return this;
}
public Builder progressListener(ProgressListener progressListener) {
this.progressListener = progressListener;
return this;
}
public Builder before(Action0 before) {
this.before = before;
return this;
}
public Builder filter(Action1 filter) {
this.filter = filter;
return this;
}
public Builder loadable(FileLoadable loadable) {
this.loadable = loadable;
return this;
}
public Builder dialogTitle(String dialogTitle) {
this.dialogTitle = dialogTitle;
return this;
}
public Builder dialogContent(String dialogContent) {
this.dialogContent = dialogContent;
return this;
}
public Builder requestService(UploadFilesCall requestService) {
this.requestService = requestService;
return this;
}
public Builder callback(HttpCallback callback) {
this.callback = callback;
return this;
}
public Builder fileParams(String fileParams) {
this.fileParams = fileParams;
return this;
}
public Subscription toSubscribe() {
return new UploadFiles<>(this).startUpload();
}
}
}