4

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();
    });
}
4

1 に答える 1