RxJava retryWhen操作符實現錯誤重試機制
阿新 • • 發佈:2019-01-05
業務需求
當我們在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
可以發現,在第三次重試的時候,伺服器可用了。