簡體   English   中英

在Retrofit Android中手動重試請求的好方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM