3

サーバーを呼び出して情報をダウンロードし、送信されたバイナリデータを解析する単純なラッパーを作成しようとしています。接続には okhttp というライブラリを使用しています。3G での接続はあまり信頼できないため、次の関数を使用して非常に単純な再試行機能を実装することにしました**(このメソッドは常にバックグラウンド スレッドから呼び出されることに注意してください)。 )**

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;
}
4

2 に答える 2

0

あなたのシナリオは、 Failsafe の OkHttpサポートを使用して非常に簡単に処理できます。

RetryPolicy<Response> retryPolicy = RetryPolicy.builder()
  .handle(ConnectionErrorException.class)
  .withMaxRetries(3)
  .withDelay(Duration.ofSeconds(5))
  .build();
Call call = client.newCall(request);
FailsafeCall failsafeCall = FailsafeCall.with(retryPolicy).compose(call);

// Execute with retries
Response response = failsafeCall.execute();

これは、同期および非同期の実行で機能し、キャンセルをサポートします。RetryPolicyは、他のさまざまな構成もサポートしています。

于 2022-02-15T16:12:29.150 に答える