[英]Good approach to manually retry requests in Retrofit Android
我了解翻新會自動重試失敗,但我想檢查特定的錯誤。 如果錯誤是由於某個HTTP代碼引起的,那么我需要在修改后重試該請求。
使用同步調用可以輕松完成此操作,但是我正在進行異步調用(通過傳遞回調)。 當我在回調中收到錯誤時,我想重試請求-但我僅有的就是RetrofitError對象(並且我丟失了請求正文)。
我有多個來自同一活動的請求(同時發生),所以我避免保存所有請求並在成功后將其無效。
是否有更好的方法來滿足此要求?
這是您可以嘗試的方法。 首先是網絡請求方法:
void getDataFromServer(final int dataId) {
...
dataService.getDataFromServer(dataId, new Callback<ResultData>() {
@Override
public void success(final ResultData data, final Response response) {
retries.set(0);
...
}
@Override
public void failure(RetrofitError error) {
if (RetrofitErrorHandler.retry(activity, progressDialog, error, retries, activity.getString(R.string.error_getting_data))) {
getDataFromServer(dataId);// retry this method
} else {
// let user know we counldn't get data
...
}
}
});
}
在這里,您可以檢查是否應重試該請求,如果應該重試,則返回true,否則,則返回false。
重試的前半部分檢查錯誤的狀態碼(請參見r.getStatus()
)是否等於您感興趣的狀態碼(請參見STATUS_CODE_RETRY
),該狀態碼可以是任何服務器狀態碼(例如401、404等)。 )。
重試的后半部分首先檢查是否是網絡錯誤(請參閱error.isNetworkError()
),如果是,則它增加重試計數器並返回true,這意味着將重試網絡請求。 如果錯誤是網絡錯誤(請參閱error.isNetworkError()
),並且重試計數器大於所需的最大重試次數(請參見NUM_RETRIES
),那么它將返回false,以便不會再次觸發請求。 下一部分是無連接檢查,其中發生了網絡錯誤,但不是超時,因此它一定是連接問題。 該檢查返回false,因為不應重試網絡請求,並且應將連接問題通知用戶。 最后的檢查是非網絡錯誤檢查,它表示發生的錯誤不是網絡錯誤的結果。 再次返回false,因此不會重試該請求並通知用戶。
public static boolean retry(Activity act, RetrofitError error, AtomicInteger retries, String uploadErrorMsg){
// this is the first half of the retry check
Response r = error.getResponse();
if (r != null && r.getStatus() == STATUS_CODE_RETRY){
Log.v(TAG, "STATUS_CODE_RETRY!");
...
return true;
}
// this is the second half of the retry check
if (error.isNetworkError()) {
if (error.getCause() instanceof SocketTimeoutException) {//connection timeout check
if(retries.incrementAndGet() < NUM_RETRIES){ // retry if you can
return true;
} else { // if you can't retry anymore
retries.set(0);
Log.i(TAG, act.getClass().getSimpleName() + " has no more retries " + act.getString(R.string.timeout_msg));
return false;
}
} else {//no connection check
retries.set(0);
Log.i(TAG, act.getClass().getSimpleName() + " " + act.getString(R.string.timeout_msg)+ " " + uploadErrorMsg);
return false;
}
} else { //non network error check
retries.set(0);
Log.i(TAG, act.getClass().getSimpleName() + " " + act.getString(R.string.err_msg)+ " " + uploadErrorMsg);
return false;
}
}
希望這會有所幫助。
如果您使用OkHttp作為HttpClient
並已更新為Retrofit
> = 1.9.0
則可以使用新的Interceptor 。 具體來說, 應用程序攔截器將讓您retry and make multiple calls
。
您可以看到我在類似問題上發布的示例偽代碼,用於處理過期的令牌。
另請注意,根據此GitHub票證 , Retrofit 2.0
將具有Interceptors
。 這將消除對OkHttp
的依賴,盡管我仍然建議使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.