版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_31093133/article/details/82744945
rxjava+retrofit访问网络的时候,我们经常需要用到超时重试的机制,这个时候需要用到retryWhen操作符,而retryWhen操作符需要传入参数:
(final Func1<? super Observable<? extends Throwable>, ? extends Observable<?>> notificationHandler)
我们可以将重试方法封装一下,以后就可以直接使用啦!
封装如下:
public class RetryWithDelay implements
Func1<Observable<? extends Throwable>, Observable<?>> {
private static final int DEFAULT_RETRIES = 4;
public static final int TYPE_RETRY_DEFAULT = -1; // 默认方式:第一次失败马上重试(快速重试),第二次隔1s,第三次隔4s,第四次隔10s
public static final int TYPE_RETRY_ENDLESS = -2; // 无限重试:0s,1s,4s,10s,30s,30s,30s无限
public static final int TYPE_RETRY_TIME = -3; // 无限重试:自定义间隔
private int maxRetries = DEFAULT_RETRIES;
private int retryDelayMillis = 500;
private int retryCount = 0;
private Action1 action1;
public RetryWithDelay(int maxRetries, int retryDelayMillis) {
this(maxRetries, retryDelayMillis, null);
}
public RetryWithDelay(int maxRetries) {
this(maxRetries, 0, null);
}
public RetryWithDelay(int maxRetries, Action1 action1) {
this(maxRetries, 0, action1);
}
public RetryWithDelay(int maxRetries, int retryDelayMillis, Action1 action1) {
this.maxRetries = maxRetries;
this.retryDelayMillis = retryDelayMillis;
this.action1 = action1;
}
@Override
public Observable<?> call(Observable<? extends Throwable> attempts) {
Observable<?> retryObservable = attempts.flatMap(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
if (checkRetry()) {
// When this Observable calls onSafeNext, the original Observable will be retried (i.e. re-subscribed).
return Observable.timer(getDelay(), TimeUnit.MILLISECONDS);
}
// Max retries hit. Just pass the error along.
return Observable.error(throwable);
}
}).onErrorResumeNext(new Func1<Throwable, Observable<?>>() {
@Override
public Observable<?> call(Throwable throwable) {
return Observable.error(throwable);
}
});
if (action1 == null) {
return retryObservable;
} else {
return retryObservable.doOnNext(action1);
}
}
/**
* 判断是否需要重试
*/
private boolean checkRetry() {
retryCount++;
return (maxRetries == TYPE_RETRY_DEFAULT && retryCount <= DEFAULT_RETRIES) // 默认重试DEFAULT_RETRIES次
|| maxRetries == TYPE_RETRY_ENDLESS // 无限重试
|| maxRetries == TYPE_RETRY_TIME //无限定时重试
|| retryCount <= maxRetries; // 自定义重试
}
/**
* 获取重试间隔
*/
private int getDelay() {
if (maxRetries == TYPE_RETRY_DEFAULT || maxRetries == TYPE_RETRY_ENDLESS) {
switch (retryCount) {
case 1:
retryDelayMillis = 0;
break;
case 2:
retryDelayMillis = 1000;
break;
case 3:
retryDelayMillis = 4000;
break;
case 4:
retryDelayMillis = 10000;
break;
default:
retryDelayMillis = 30000;
break;
}
}
return retryDelayMillis;
}
}
使用方式示例:
.retryWhen(new RetryWithDelay(TYPE_RETRY_DEFAULT))//默认方式
.retryWhen(new RetryWithDelay(RetryWithDelay.TYPE_RETRY_ENDLESS))//无限重试方式
.retryWhen(new RetryWithDelay(RetryWithDelay.TYPE_RETRY_TIME, 5000))//自定义重试间隔,单位是毫秒