restApi.fetchSomeData()
.retry(5) // Retry the call 5 times if it errors
.subscribeOn(Schedulers.io()) // execute the call asynchronously
.observeOn(AndroidSchedulers.mainThread()) // handle the results in the ui thread
.subscribe(onComplete, onError);
// onComplete and onError are of type Action1<DataResponse>, Action1<Throwable>
// Here you can define what to do with the results
我遇到了和你一样的问题,这实际上是我的解决方案 . RxJava是一个非常好的库,可与Retrofit结合使用 . 除了重试之外,你甚至可以做很多很酷的事情(例如composing and chaining calls) .
final Observable<List<NewsDatum>> newsDetailsObservable = apiService.getCandidateNewsItem(newsId).map((newsDetailsParseObject) -> {
return newsDetailsParseObject;
});
newsDetailsObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.retry((integer, throwable) -> {
//MAX_NUMBER_TRY is your maximum try number
if(integer <= MAX_NUMBER_TRY){
return true;//this will retry the observable (request)
}
return false;//this will not retry and it will go inside onError method
})
.subscribe(new Subscriber<List<NewsDatum>>() {
@Override
public void onCompleted() {
// do nothing
}
@Override
public void onError(Throwable e) {
//do something with the error
}
@Override
public void onNext(List<NewsDatum> apiNewsDatum) {
//do something with the parsed data
}
});
11 回答
我发现当http连接失败时,Sinan Kozak提供的方式(OKHttpClient intercepter)不起作用,还没有关注HTTP响应 .
所以我用另一种方法来挂钩Observable对象,在它上面调用.retryWhen . 另外,我添加了retryCount限制 .
然后
然后添加或替换
同
例如:
注意:为简单起见,我只是将HTTP代码> 404代码视为重试,请自行修改 .
此外,如果http响应为200,那么上面的
rx.retryWhen
将不会被调用,如果你坚持检查这样的响应,你可以在.retryWhen之前添加rx.subscribeOn(...throw error...
.For Retrofit 1.x;
你可以使用Interceptors . 创建自定义拦截器
并在创建RestAdapter时使用它 .
For Retrofit 2.x;
您可以使用Call.clone()方法克隆请求并执行它 .
我不知道这是否适合您,但您可以将RxJava与Retrofit一起使用 .
Retrofit能够在休息时调用Observables . 在Oberservables上,您可以在发出错误时调用
retry(count)
重新订阅Observable .您必须在界面中定义调用,如下所示:
然后你可以像这样订阅这个Observable:
我遇到了和你一样的问题,这实际上是我的解决方案 . RxJava是一个非常好的库,可与Retrofit结合使用 . 除了重试之外,你甚至可以做很多很酷的事情(例如composing and chaining calls) .
response.isSuccessful()的问题是当你有一个像SocketTimeoutException这样的异常时 .
我修改了原始代码来修复它 .
希望能帮助到你 . 问候 .
对于那些更喜欢拦截器来处理重试的问题 - 在Sinan的答案的基础上,这里是我提出的拦截器,其中包括重试计数和退避延迟,并且只在网络可用时重试尝试,并且当请求不是时取消 . (仅处理IOExceptions(SocketTimeout,UnknownHost等))
礼貌地回答,这对我有用 . 如果存在连接问题,最好在重试前等待几秒钟 .
}
我认为你不应该混合API处理(由retrofit / okhttp完成)和重试 . 重试机制更正交,也可以在许多其他环境中使用 . 所以我使用Retrofit / OkHTTP进行所有API调用和请求/响应处理,并在上面引入另一个层,用于重试API调用 .
在我迄今为止有限的Java经验中,我发现jhlaterman的Failsafe库(github:jhalterman/failsafe)是一个非常通用的库,可以干净地处理许多情况 . 作为一个例子,我将如何使用它与改进的实例化mySimpleService进行身份验证 -
上面的代码捕获套接字异常,连接错误,断言失败,并最多重试3次,指数退避 . 它还允许您自定义重试行为,并允许您指定回退 . 它非常易于配置,可以适应大多数重试情况 .
随意检查库的文档,因为除了重试之外它还提供许多其他好东西 .
它似乎将出现在API Spec:https://github.com/square/retrofit/issues/297的改进2.0中 . 目前,最好的方法似乎是捕获异常并手动重试 .
如docs中所述,更好的方法是在验证器中使用烘焙,例如:private final OkHttpClient client = new OkHttpClient();
我已经尝试了很多这个问题,试图找到重试Retrofit请求的最佳方法 . 我正在使用Retrofit 2,所以我的解决方案是Retrofit 2.对于Retrofit 1,你必须使用Interceptor,就像这里接受的答案一样 . @joluet的答案是正确的,但他没有提到需要在.subscribe(onComplete,onError)方法之前调用重试方法 . 这非常重要,否则请求不会再次重试@pocmo在@joluet中提到了答案 . 这是我的例子:
apiService是我的RetrofitServiceProvider对象 .
顺便说一句:我使用的是Java 8,因此代码中有很多lambda表达式 .
只想分享我的版本 . 它使用rxJava retryWhen方法 . 我的版本每N = 15秒重试连接,并在互联网连接恢复时几乎立即发出重试 .
你应该在之前使用它.subscribe如下:
您应该手动更改isInternetUp字段