当我们在app里发起网络请求时,可能会因为各种问题导致失败。如何利用RxJava来实现出现错误后重试若干次,并且可以设定重试的时间间隔。
网络请求使用Retrofit来做,还是使用上篇博客中的请求用户信息接口
@GET("/userinfo?noToken=1") Observable<Response> getUserInfoNoToken();
下面是请求用户信息接口
的逻辑代码
userApi.getUserInfoNoToken()
//总共重试3次,重试间隔3000毫秒
.retryWhen(new RetryWithDelay(3, 3000))
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Action1<Response>() {
@Override
public void call(Response response) {
String content = new String(((TypedByteArray) response.getBody()).getBytes());
printLog(tvLogs, "", content);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});
RetryWithDelay
public class RetryWithDelay implements Func1<Observable<? extends Throwable>, Observable<?>> { private final int maxRetries; private final int retryDelayMillis; private int retryCount; public RetryWithDelay(int maxRetries, int retryDelayMillis) { this.maxRetries = maxRetries; this.retryDelayMillis = retryDelayMillis; } @Override public Observable<?> call(Observable<? extends Throwable> attempts) { return attempts .flatMap(new Func1<Throwable, Observable<?>>() { @Override public Observable<?> call(Throwable throwable) { if (++retryCount <= maxRetries) { // When this Observable calls onNext, the original Observable will be retried (i.e. re-subscribed). printLog(tvLogs, "", "get error, it will try after " + retryDelayMillis + " millisecond, retry count " + retryCount); return Observable.timer(retryDelayMillis, TimeUnit.MILLISECONDS); } // Max retries hit. Just pass the error along. return Observable.error(throwable); } }); } }
如何模拟重试呢?
方法一:把服务器关闭,关闭服务器后,客户端请求接口的必然会报错,看看是不是重试三次。
运行输出:
'get error, it will try after 3000 millisecond, retry count 1'
Main Thread:false, Thread Name:Retrofit-Idle
'get error, it will try after 3000 millisecond, retry count 2'
Main Thread:false, Thread Name:Retrofit-Idle
'get error, it will try after 3000 millisecond, retry count 3'
Main Thread:false, Thread Name:Retrofit-Idle
上面是重试三次了,但是我们怎么知道,如果在服务器启动后,在接下的重试中请求成功呢?接下来试试方法二。
方法二:先把服务器关闭,当点击按钮请求的同时,启动Tomcat服务器。
运行输出:
'get error, it will try after 3000 millisecond, retry count 1'
Main Thread:false, Thread Name:Retrofit-Idle
'get error, it will try after 3000 millisecond, retry count 2'
Main Thread:false, Thread Name:Retrofit-Idle
'username:chiclaim,age:007'
Main Thread:true, Thread Name:main
可以发现,在第三次重试的时候,服务器可用了。
github源码下载