Retrofit を使用してサーバーと通信するアプリを構築しています。ネットワーク エラーが発生した場合は、ダイアログ (トーストと同等) が表示され、ユーザーがダイアログをクリックした後に要求がやり直されます。問題は、リクエストごとに重複したコードを記述するのではなく、グローバルに処理したいということです。この質問でonErrorResumeNext()
a.bertucciが説明したように、監視可能なビューイベントを使用すると完璧に見えますが、残念ながらスレッドで実行され、UI要素を開始できません。それを解決することは可能ですか?Retrofit.Idle
失敗した例:
public static <T> Func1<Throwable, ? extends Observable<? extends T>> retryOnNetworkError(final Activity activity, final Observable<T> toBeResumed) {
return new Func1<Throwable, Observable<? extends T>>() {
@Override
public Observable<? extends T> call(Throwable throwable) {
if (throwable instanceof RetrofitError &&
RetrofitUtils.isNetworkError((RetrofitError) throwable)) {
return dialog(activity, R.string.dialog_title_network_error, R.string.dialog_msg_network_error)
.filter(ok -> ok)
.flatMap(ok -> toBeResumed);
}
return Observable.error(throwable);
}
};
}
public static Observable<Boolean> dialog(Context context, int title, int message) {
return Observable.create((Subscriber<? super Boolean> subscriber) -> {
final AlertDialog ad = new AlertDialog.Builder(context)
.setTitle(title)
.setMessage(message)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
subscriber.onNext(true);
subscriber.onCompleted();
})
.setNegativeButton(android.R.string.cancel, (dialog, which) -> {
subscriber.onNext(false);
subscriber.onCompleted();
})
.create();
// cleaning up
subscriber.add(Subscriptions.create(ad::dismiss));
ad.show();
});
}