OkHttp中的retryOnConnectionFailure(true)方法可以实现错误重试,但不支持自定义重试次数。
1.通过自定义一个Interceptor实现错误重试次数。
1.1自定义RetryInterceptor
public class RetryInterceptor implements Interceptor
{
public int executionCount; // 最大重试次数
private long retryInterval; // 重试的间隔
RetryInterceptor(Builder builder)
{
this.executionCount = builder.executionCount;
this.retryInterval = builder.retryInterval;
}
@Override
public Response intercept(Chain chain) throws IOException
{
Request request = chain.request();
Response response = chain.proceed(request);
int retryNum = 0;
while ((response == null || !response.isSuccessful()) && retryNum <= executionCount)
{
final long nextInterval = getRetryInterval();
try
{
Thread.sleep(nextInterval);
}
catch (final InterruptedException e)
{
Thread.currentThread().interrupt();
throw new InterruptedIOException();
}
retryNum++;
response = chain.proceed(request);
}
return response;
}
/**
* retry间隔时间
*/
public long getRetryInterval()
{
return this.retryInterval;
}
public static final class Builder
{
private int executionCount;
private long retryInterval;
public Builder()
{
executionCount = 3;
retryInterval = 1000;
}
public Builder executionCount(int executionCount)
{
this.executionCount = executionCount;
return this;
}
public Builder retryInterval(long retryInterval)
{
this.retryInterval = retryInterval;
return this;
}
public RetryInterceptor build()
{
return new RetryInterceptor(this);
}
}
}
1.2 调用
private RetrofitHelper()
{
// 错误重连拦截器
RetryInterceptor retryInterceptor = new RetryInterceptor.Builder()
.executionCount(5)
.retryInterval(3000).build();
ClearableCookieJar cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(BaseApplication.getInstance()));
OkHttpClient.Builder client = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
// 错误重连
.addInterceptor(retryInterceptor);
OkHttpClient okHttpClient = client.build();
retrofit = new Retrofit.Builder()
.baseUrl(UrlManager.BASE_API_SERVER_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
}
2.通过rxjava实现错误重试次数。
2.1自定义RetryException
public class RetryException implements Function<Observable<? extends Throwable>, Observable<?>>
{
/* retry次数*/
private int count = 0;
/*延迟*/
private long delay = 500;
/*叠加延迟*/
private long increaseDelay = 3000;
public RetryException()
{
}
public RetryException(int count, long delay)
{
this.count = count;
this.delay = delay;
}
public RetryException(int count, long delay, long increaseDelay)
{
this.count = count;
this.delay = delay;
this.increaseDelay = increaseDelay;
}
@Override
public Observable<?> apply(@NonNull Observable<? extends Throwable> observable) throws Exception
{
return observable.zipWith(Observable.range(1, count + 1), new BiFunction<Throwable, Integer, Wrapper>()
{
@Override
public Wrapper apply(@NonNull Throwable throwable, @NonNull Integer integer) throws Exception
{
return new Wrapper(throwable, integer);
}
}).flatMap(new Function<Wrapper, ObservableSource<?>>()
{
@Override
public ObservableSource<?> apply(@NonNull Wrapper wrapper) throws Exception
{
if (wrapper.index > 1)
{
LogUtils.d("重试次数:" + (wrapper.index));
}
int errCode = 0;
if (wrapper.throwable instanceof ApiException)
{
ApiException exception = (ApiException) wrapper.throwable;
errCode = exception.getCode();
}
if ((wrapper.throwable instanceof ConnectException || wrapper.throwable instanceof SocketTimeoutException || errCode == ApiException.ERROR.NETWORD_ERROR || errCode == ApiException.ERROR.TIMEOUT_ERROR || wrapper.throwable instanceof SocketTimeoutException || wrapper.throwable instanceof TimeoutException) && wrapper.index < count + 1)
{
// 如果超出重试次数也抛出错误,否则默认是会进入onCompleted
return Observable.timer(delay + (wrapper.index - 1) * increaseDelay, TimeUnit.MILLISECONDS);
}
return Observable.error(wrapper.throwable);
}
});
}
private class Wrapper
{
private int index;
private Throwable throwable;
public Wrapper(Throwable throwable, int index)
{
this.index = index;
this.throwable = throwable;
}
}
}
2.1调用
private RetrofitHelper()
{
OkHttpClient.Builder client = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
OkHttpClient okHttpClient = client.build();
retrofit = new Retrofit.Builder()
.baseUrl(UrlManager.BASE_URL_WEATHER)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build();
}