com.cmonbaby.http.stream.upload.UploadFile 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 okhttp3.MediaType;
import okhttp3.MultipartBody;
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 UploadFile {
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 String fileType; // 文件类型
private final String filePath; // 文件路径
private String fileParams; // 上传文件参数名
private final UploadFileCall requestService; // 上传单个文件时,将MultipartBody.Part组装Observable
private final HttpCallback callback; // Http请求回调
private UploadFile(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.fileType = builder.fileType;
this.filePath = builder.filePath;
this.fileParams = builder.fileParams;
this.requestService = builder.requestService;
this.callback = builder.callback;
}
private Subscription startUpload() {
if (callback == null) {
Log.e("初始化callback错误", "请实现:callback(new HttpCallback())方法");
return null;
}
if (TextUtils.isEmpty(filePath)) {
Log.e("filePath为空", "filePath为文件详细路径,不能为空!");
return null;
}
File file = new File(filePath); // 注:filePath为文件详细路径,末尾包含文件名
if (!file.exists()) {
Log.e("!file.exists()", "filePath为文件详细路径,末尾包含文件名:" + filePath);
return null;
}
if (TextUtils.isEmpty(fileType)) fileType = "multipart/form-data";
if (TextUtils.isEmpty(fileParams)) fileParams = "file";
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);
}
});
RequestBody requestBody = RequestBody.create(MediaType.parse(fileType), file);
MultipartBody.Part part = MultipartBody.Part.createFormData(fileParams, file.getName(), requestBody);
if (requestService == null) {
Log.e("初始化requestService错误", "请实现:requestService(new UploadFileCall())方法");
return null;
}
observable = requestService.uploadFile(s, part);
if (observable == null) {
Log.e("初始化observable错误", "请检查实现:requestService(new UploadFileCall())方法");
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 String fileType = "image/png"; // 文件类型
private String filePath; // 文件路径
private String fileParams = "file"; // 上传文件参数名
private UploadFileCall requestService; // 上传转换器
private HttpCallback callback; // Http请求回调
private Builder(Class clazz, Observable observable) {
this.clazz = clazz;
this.observable = observable;
}
public static Builder upload(Class clazz, Observable observable) {
return new Builder<>(clazz, observable);
}
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 fileType(String fileType) {
this.fileType = fileType;
return this;
}
public Builder filePath(String filePath) {
this.filePath = filePath;
return this;
}
public Builder fileParams(String fileParams) {
this.fileParams = fileParams;
return this;
}
public Builder requestService(UploadFileCall requestService) {
this.requestService = requestService;
return this;
}
public Builder callback(HttpCallback callback) {
this.callback = callback;
return this;
}
public Subscription toSubscribe() {
return new UploadFile<>(this).startUpload();
}
}
}