當我們在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);
}
});
}
}
如何摹擬重試呢?
方法1:把服務器關閉,關閉服務器后,客戶端要求接口的必定會報錯,看看是否是重試3次。
運行輸出:
'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
上面是重試3次了,但是我們怎樣知道,如果在服務器啟動后,在接下的重試中要求成功呢?接下來試試方法2。
方法2:先把服務器關閉,當點擊按鈕要求的同時,啟動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
可以發現,在第3次重試的時候,服務器可用了。
github源碼下載