java - Android okHttp 重试策略

标签 java android okhttp

我正在尝试创建一个简单的包装器,它将调用服务器下载信息并解析发送的二进制数据。 对于连接,我使用名为 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;
}

最佳答案

如果捕获到 NoNetworkAvailableException,您可以避免重试。如果您知道以下尝试无论如何都会失败,请不要重试。

我会让 connectionFailedMaximumAllowedRetries() 成为常量。我怀疑您是否需要随时更改变量。

实现exponential back off .你可以让它重试 10 次。每次,您将延迟乘以 2(上限为几分钟)。例如:

  1. 尝试调用 - 失败
  2. 等一秒
  3. 尝试调用 - 失败
  4. 等待 2 秒
  5. 尝试调用 - 失败
  6. 等待 4 秒
  7. ...
  8. 尝试调用 - 成功

这是非常典型的行为。如果发生短暂的中断,调用将很快再次进行并成功。如果停电时间较长,您不希望每隔几秒就不断调用。这为您的代码提供了使其调用通过的最佳机会。显然,如果需要此调用来更改 UI,请注意不要惹恼用户。

关于java - Android okHttp 重试策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35057112/

相关文章:

Java对象创建区别

android - 在 Android 上使用 okhttp 2 的持久性 Cookie 存储

java - 不支持中文的 Content-Disposition 文件名

java - 在 jBoss 日志中显示/隐藏 SQL 查询

java - Maven Java 主页配置

android - 我们可以在 Android 应用程序中使用 UIAutomator 吗?

java - 从 Uri 获取位图

java - 检测是否有市场 ://link is clicked in a webview

java - 如何使用 Picasso 使用动态 URL 缓存来自 S3 存储桶的图像?

android - Http请求拦截未显示任何日志信息