Retrofit2でRxJavaとRxAndroidを使用しています。
Observable<ResponseOne> responseOneObservable = getRetrofitClient().getDataOne()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Observable<ResponseTwo> responseTwoObservable = getRetrofitClient().getDataTwo()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
上記の2つのオブザーバーでZip演算子を以下のように使用します。
Observable<ArrayList<TestData>> testDataObservable = Observable.Zip(responseOneObservable, responseTwoObservable, new Func2<ResponseOne, ResponseTwo, ArrayList<TestData>>() {
@Override
public ArrayList<TestData> call(ResponseOne responseOne, ResponseTwo responseTwo) {
ArrayList<TestData> testDataList = new ArrayList();
// Add test data from response responseOne & responseTwo
return testDataList;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ArrayList<TestData>>() {
@Override
public void onNext(ArrayList<TestData> testDataList) {
}
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted" );
}
@Override
public void onError(Throwable t) {
Log.d(TAG, "onError Throwable: " + t.toString() );
}
});
responseOneObservable
およびresponseTwoObservable
でのレトロフィットhttp呼び出し中にエラーが発生した場合、onError
のサブスクライバーのtestDataObservable
メソッドを直接呼び出します。
2つのオブザーバブルのいずれかが成功応答を受け取った場合でも、Zipオペレーターのcall
メソッドを続行します。
Zip
演算子を使用してエラー応答を処理する方法は?
次のように、onErrorResumeNext
を使用してObservableを返すか、onErrorReturn
を使用してZip
にデフォルト値を返すことができます。
Observable.Zip(
responseOneObservable
.onErrorReturn(new Func1<Throwable, ResponseOne>() {
@Override
public ResponseOne call(final Throwable throwable) {
return new ResponseOne();
}
}),
responseTwoObservable
.onErrorReturn(new Func1<Throwable, ResponseTwo>() {
@Override
public ResponseTwo call(final Throwable throwable) {
return new ResponseTwo();
}
}),
...
詳細については、 onError handling を参照してください。
UPDATE:RxJava 2.0では、Func1
の代わりにFunction
を使用する必要があります。
import io.reactivex.functions.Function;
...
Observable.Zip(
responseOneObservable
.onErrorReturn(new Function<Throwable, ResponseOne>() {
@Override
public ResponseOne apply(@NonNull final Throwable throwable) {
return new ResponseOne();
}
}),
responseTwoObservable
.onErrorReturn(new Function<Throwable, ResponseTwo>() {
@Override
public ResponseTwo apply(@NonNull final Throwable throwable) {
return new ResponseTwo();
}
}),
...
または、ラムダを使用:
Observable.Zip(
responseOneObservable
.onErrorReturn(throwable -> new ResponseOne()),
responseTwoObservable
.onErrorReturn(throwable -> new ResponseTwo()),
...
または、Kotlinを使用:
Observable.Zip(
responseOneObservable
.onErrorReturn { ResponseOne() },
responseTwoObservable
.onErrorReturn { ResponseTwo() },
...
onErrorResumeNext
演算子を使用して、2つのオブザーバブルのいずれかからデフォルトの応答を返すことができます。
Observable<ResponseOne> responseOneObservable = getRetrofitClient().getDataOne()
.onErrorResumeNext(throwable -> {/*some default value*/})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Observable<ResponseTwo> responseTwoObservable = getRetrofitClient().getDataTwo()
.onErrorResumeNext(throwable -> {/*some default value*/})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
RxJavaでのエラー処理-Dan Lew も参照してください。
単一のzipされたオブザーバブルに対してonErrorResumeNext
を使用して、エラーの場合にデフォルトアイテムを発行するよう指示する必要があります。
Error-Handling-Operators を参照してください