2016-01-28 92 views
3

我想創建一個簡單的包裝,它將調用服務器下載信息並解析發送的二進制數據。 連接我使用的庫稱爲okhttp,因爲3G上的連接並不是非常可靠我已決定使用以下函數實現一個非常簡單的重試功能**(注意,此方法將始終從後臺調用線程)**Android okHttp重試策略

private InputStream callServer() throws ServerException, NoNetworkAvailableException, ConnectionErrorException { 
     NetworkOperation networkOperation = getNetworkOperation(); 
     InputStream inputStream = null; 
     //in case of network problems we will retry 3 times separated by 5 seconds before gave up 
     while (connectionFailedRetryCounter < connectionFailedMaximumAllowedRetries()) { 
      connectionFailedRetryCounter++; 
      try { 
       inputStream = networkOperation.execute(); 
       break;//if this line was reached it means a successfull operation, no need to retry . 
      } catch (ConnectionErrorException e) { 
       if (canRetryToConnect()) { 
        Utils.forceSleepThread(Constants.Communications.ConnectionFailedTrialCounter.SLEEP_BETWEEN_REQUESTS_MILLI);//retry after 5 secs (Thread.sleep) 
       } else { 
        throw e;//I give up 
       } 
      } 

     } 
     return inputStream; 

    } 

    private boolean canRetryToConnect() { 
     return (connectionFailedRetryCounter < connectionFailedMaximumAllowedRetries()) && !canceled; 
    } 

這是這樣做的正確方法?還是已經由圖書館自己完成了(沒有必要實施這樣的任何事情)?

這裏是execute方法是什麼()做

public InputStream execute() throws ConnectionErrorException, NoNetworkAvailableException, ServerException { 

    if (!Utils.isNetworkAvailable(context)) { 
     throw new NoNetworkAvailableException(); 
    } 

    Response response = doExecute(); 

    if (!response.isSuccessful()) { 
     throw new ServerException(response.code()); 
    } 

    return response.body().byteStream(); 
} 

private Response doExecute() throws ConnectionErrorException { 
    Response response; 
    try { 
     if (getRequestType() == RequestType.GET) { 
      response = executeGet(); 
     } else { 
      response = executePost(); 
     } 
    } catch (IOException e) { 
     throw new ConnectionErrorException(); 
    } 
    return response; 
} 

回答

1

你能避免重試,如果你趕上NoNetworkAvailableException。不要重試,如​​果你知道以下嘗試將失敗。

我會讓connectionFailedMaximumAllowedRetries()一個常數。我懷疑你需要在任何時候改變這個變量。

實施exponential back off。你可以重試10次。每次您將延遲乘以2(用幾分鐘的上限)。例如:

  1. 嘗試呼叫 - 失敗
  2. 等待1秒
  3. 嘗試呼叫 - 失敗
  4. 等待2秒
  5. 嘗試呼叫 - 失敗
  6. 等待4秒
  7. ..
  8. 嘗試撥打電話 - 成功

這是非常典型的行爲。如果發生短暫停電事件,呼叫將很快恢復併成功。如果發生較長時間的停電,您不希望每隔幾秒鐘不斷地打電話。這爲您的代碼提供了通話過程中的最佳機會。顯然,如果此調用是UI更改所需的,應該注意不要讓用戶煩惱。

+0

我只在ConnectionErrorException的情況下重新嘗試,如果任何其他異常發生(例如:NoNetworkAvailableException)循環會中斷,異常將傳播到下一級(仍然認爲我的代碼複雜,不可讀因爲我會努力簡化流程)。指數後退的想法很好 –