rxjava: Can I use retry() but with delay?

后端 未结 14 2302
别那么骄傲
别那么骄傲 2020-11-28 18:25

I am using rxjava in my Android app to handle network requests asynchronously. Now I would like to retry a failed network request only after a certain time has passed.

14条回答
  •  难免孤独
    2020-11-28 19:02

    You can use the retryWhen() operator to add retry logic to any Observable.

    The following class contains the retry logic:

    RxJava 2.x

    public class RetryWithDelay implements Function, Observable> {
        private final int maxRetries;
        private final int retryDelayMillis;
        private int retryCount;
    
        public RetryWithDelay(final int maxRetries, final int retryDelayMillis) {
            this.maxRetries = maxRetries;
            this.retryDelayMillis = retryDelayMillis;
            this.retryCount = 0;
        }
    
        @Override
        public Observable apply(final Observable attempts) {
            return attempts
                    .flatMap(new Function>() {
                        @Override
                        public Observable apply(final Throwable throwable) {
                            if (++retryCount < maxRetries) {
                                // When this Observable calls onNext, the original
                                // Observable will be retried (i.e. re-subscribed).
                                return Observable.timer(retryDelayMillis,
                                        TimeUnit.MILLISECONDS);
                            }
    
                            // Max retries hit. Just pass the error along.
                            return Observable.error(throwable);
                        }
                    });
        }
    }
    

    RxJava 1.x

    public class RetryWithDelay implements
            Func1, Observable> {
    
        private final int maxRetries;
        private final int retryDelayMillis;
        private int retryCount;
    
        public RetryWithDelay(final int maxRetries, final int retryDelayMillis) {
            this.maxRetries = maxRetries;
            this.retryDelayMillis = retryDelayMillis;
            this.retryCount = 0;
        }
    
        @Override
        public Observable call(Observable attempts) {
            return attempts
                    .flatMap(new Func1>() {
                        @Override
                        public Observable call(Throwable throwable) {
                            if (++retryCount < maxRetries) {
                                // When this Observable calls onNext, the original
                                // Observable will be retried (i.e. re-subscribed).
                                return Observable.timer(retryDelayMillis,
                                        TimeUnit.MILLISECONDS);
                            }
    
                            // Max retries hit. Just pass the error along.
                            return Observable.error(throwable);
                        }
                    });
        }
    }
    

    Usage:

    // Add retry logic to existing observable.
    // Retry max of 3 times with a delay of 2 seconds.
    observable
        .retryWhen(new RetryWithDelay(3, 2000));
    

提交回复
热议问题