com.cmonbaby.http.core.zip.Zip3Helper Maven / Gradle / Ivy
package com.cmonbaby.http.core.zip;
import android.text.TextUtils;
import android.util.Log;
import com.cmonbaby.http.core.HttpCallback;
import com.cmonbaby.http.dialog.HttpLoadable;
import com.cmonbaby.http.schedulers.AndroidSchedulers;
import rx.Observable;
import rx.Observer;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func3;
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:
* 多异步请求并发,不分顺序时。等待所有异步完成再做操作。多用多图片上传等
* 拼接多个Observable的输出,不保证顺序,按照事件产生的顺序发送给订阅者
*/
public class Zip3Helper {
private final Observable observable1; // 从retrofit返回的第一个请求 Observable。被观察者
private final Observable observable2; // 从retrofit返回的第二个请求 Observable。被观察者
private final Observable observable3; // 从retrofit返回的第三个请求 Observable。被观察者
private final Action0 before; // http请求开始的时候一些界面上的处理
private final Action1 result1; // 第一个http请求完成时
private final Action1 result2; // 第二个http请求完成时
private final Action1 result3; // 第三个http请求完成时
private final Func3 result;
private final HttpLoadable loadable; // 对于activity和fragment loading的处理
private final String dialogTitle; // loading标题
private String dialogContent; // loading内容摘要
private final HttpCallback callback; // Http请求回调
private Zip3Helper(Builder builder) {
this.observable1 = builder.observable1;
this.observable2 = builder.observable2;
this.observable3 = builder.observable3;
this.before = builder.before;
this.result1 = builder.result1;
this.result2 = builder.result2;
this.result3 = builder.result3;
this.result = builder.result;
this.loadable = builder.loadable;
this.dialogTitle = builder.dialogTitle;
this.dialogContent = builder.dialogContent;
this.callback = builder.callback;
}
private Subscription startWork() {
if (observable1 == null || observable2 == null || observable3 == null) {
Log.e("初始化observable错误", "observable == null");
return null;
}
if (callback == null) {
Log.e("初始化callback错误", "请实现:callback(new HttpCallback())方法");
return null;
}
if (TextUtils.isEmpty(dialogContent)) dialogContent = "加载中,请稍候……";
Observer httpCallback = new Observer() {
@Override
public void onCompleted() {
if (loadable != null && !loadable.isKeepShowing()) loadable.dismissHttpDialog();
}
@Override
public void onError(Throwable e) {
if (loadable != null) loadable.dismissHttpDialog();
callback.onError(e);
}
@Override
public void onNext(T t) {
callback.onSuccessful(t);
}
};
Observable a1Observable = observable1.subscribeOn(Schedulers.io()) // 是http请求的操作是在io线程中调用,而不是UI线程中。
.observeOn(AndroidSchedulers.mainThread()) // 确保subscriber的回调,即onNext、onError和onCompleted是在Ui线程中回调
.subscribeOn(AndroidSchedulers.mainThread()) // 这里切换到UI线程,确保doOnSubscribe在UI线程中进行,以便subscribe回调是在UI线程中进行。
.doOnNext(a1 -> { // 处理
if (result1 != null) result1.call(a1); // 进行额外的界面处理,在http请求开始的时候
});
Observable a2Observable = observable2.subscribeOn(Schedulers.io()) // 是http请求的操作是在io线程中调用,而不是UI线程中。
.observeOn(AndroidSchedulers.mainThread()) // 确保subscriber的回调,即onNext、onError和onCompleted是在Ui线程中回调
.subscribeOn(AndroidSchedulers.mainThread()) // 这里切换到UI线程,确保doOnSubscribe在UI线程中进行,以便subscribe回调是在UI线程中进行。
.doOnNext(a2 -> { // 处理
if (result2 != null) result2.call(a2); // 进行额外的界面处理,在http请求开始的时候
});
Observable a3Observable = observable3.subscribeOn(Schedulers.io()) // 是http请求的操作是在io线程中调用,而不是UI线程中。
.observeOn(AndroidSchedulers.mainThread()) // 确保subscriber的回调,即onNext、onError和onCompleted是在Ui线程中回调
.subscribeOn(AndroidSchedulers.mainThread()) // 这里切换到UI线程,确保doOnSubscribe在UI线程中进行,以便subscribe回调是在UI线程中进行。
.doOnNext(a3 -> { // 处理
if (result3 != null) result3.call(a3); // 进行额外的界面处理,在http请求开始的时候
});
return Observable.zip(a1Observable, a2Observable, a3Observable, (a1, a2, a3) -> {
if (result != null) return result.call(a1, a2, a3); // 进行额外的界面处理,在http请求开始的时候
return null;
})
.subscribeOn(Schedulers.io()) // 是http请求的操作是在io线程中调用,而不是UI线程中。
.observeOn(AndroidSchedulers.mainThread()) // 确保subscriber的回调,即onNext、onError和onCompleted是在Ui线程中回调
.doOnSubscribe(() -> {
if (loadable != null) loadable.showDialog(); // 如果不为空,就进行loading的show操作
if (loadable != null) loadable.setHttpDialogTitle(dialogTitle);
if (loadable != null) loadable.setHttpDialogContent(dialogContent);
if (before != null) before.call(); // 进行额外的界面处理,在http请求开始的时候
}) // http请求开始时,一些初始化的操作。比如loading界面的显示
.subscribeOn(AndroidSchedulers.mainThread()) // 这里切换到UI线程,确保doOnSubscribe在UI线程中进行,以便subscribe回调是在UI线程中进行。
.subscribe(httpCallback);
}
public static final class Builder {
private final Observable observable1; // 从retrofit返回的第一个请求 Observable。被观察者
private final Observable observable2; // 从retrofit返回的第二个请求 Observable。被观察者
private final Observable observable3; // 从retrofit返回的第三个请求 Observable。被观察者
private Action0 before; // http请求开始的时候一些界面上的处理
private Action1 result1; // 第一个http请求完成时
private Action1 result2; // 第二个http请求完成时
private Action1 result3; // 第三个http请求完成时
private Func3 result;
private HttpLoadable loadable; // 对于activity和fragment loading的处理
private String dialogTitle; // loading标题
private String dialogContent; // loading内容摘要
private HttpCallback callback; // Http请求回调
private final Class clazz;
private Builder(Observable observable1, Observable observable2, Observable observable3, Class clazz) {
this.observable1 = observable1;
this.observable2 = observable2;
this.observable3 = observable3;
this.clazz = clazz;
}
public static Builder builder(Observable observable1, Observable observable2, Observable observable3, Class clazz) {
return new Builder<>(observable1, observable2, observable3, clazz);
}
public Builder before(Action0 before) {
this.before = before;
return this;
}
public Builder result1(Action1 result1) {
this.result1 = result1;
return this;
}
public Builder result2(Action1 result2) {
this.result2 = result2;
return this;
}
public Builder result3(Action1 result3) {
this.result3 = result3;
return this;
}
public Builder result(Func3 result) {
this.result = result;
return this;
}
public Builder loadable(HttpLoadable 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 callback(HttpCallback callback) {
this.callback = callback;
return this;
}
private Zip3Helper request() {
return new Zip3Helper<>(this);
}
public Subscription toSubscribe() {
if (clazz == null) return null;
Zip3Helper zipHelper = request();
return zipHelper.startWork();
}
}
}