重新尝试使用哪种HttpURLConnection方法是明智的?

时间:2016-03-24 20:51:04

标签: java android http

以下java代码在IntentService中运行;有用;它将图像上传到twitter。 我在每次调用抛出IOException时都用一个单独的try-catch编写它。 我已经删除了......位置的代码,以便更快地阅读。

try {
    con = (HttpURLConnection) new URL(Constants.TWITTER_ENDPOINT_UPLOAD_MEDIA).openConnection();
} catch (IOException e) {
    e.printStackTrace();
}

...

con.setDoOutput(true);
try {
    os = con.getOutputStream();
} catch (IOException e) {
    e.printStackTrace();
}

DataOutputStream out = new DataOutputStream(os);
try {
    write(out, boundary + "\r\n");
    ...
} catch (IOException e) {
    e.printStackTrace();
}

try {
    statusCode = con.getResponseCode();
} catch (IOException e) {
    e.printStackTrace();
}

我的问题是: 将一个或多个这些调用置于重试循环中是否有意义,如下所示:

for (int i = 0; ; i++) {
    try {
        httpURLConnection = (HttpURLConnection) new URL(Constants.TWITTER_ENDPOINT_UPLOAD_MEDIA).openConnection();
        break;
    }
    catch (IOException e) {
        if (i < 3) {
            continue;
        }
        else {
            reportErrorToCallingActivity();
            return;
        }
    }
}

而且,如果它确实有意义,哪些? 而且,如果我需要重新尝试:

statusCode = con.getResponseCode();

我应该重新运行多少代码:一直回到openConnection? 我只能从文档中弄清楚这一点, 我不想猜测该怎么做。希望你能帮忙!

1 个答案:

答案 0 :(得分:0)

我很欣赏这可能会大大减少,但我认为这里的赠品是,当你抓住你的IOException时,你所做的就是将它们记录到控制台。换句话说,您的代码不知道该做什么,它处于什么状态(或连接),或者如何继续。鉴于检查异常消息文本是不好的做法,异常类型不能提供足够好的信息。在这种情况下,最简单和最诚实的事情是重新抛出原始异常,希望调用代码知道更多/可以更好地处理错误。

如果在任何阶段,您(或您的代码)确信您可以完全/大部分处理异常,那么然后会有一个明确的尝试/捕获当前代码的方式。但是,如果你不这样做,你的方法就应该“快速完成”。并声明它throws IOException而不试图处理它们。 (确保您有一个finally块来清理您在此过程中创建的所有资源!)

如果您的方法是诚实的并且在自身之后进行清理,则调用方法可能会在循环中重试 - 根据您的第二个代码示例。但是,如果没有任何重试控制(尝试次数,退避等)并且没有来自连接API的任何良好指导,那么继续尝试可能是不明智的,可能会浪费资源,限制速率,破坏T&amp; Cs等。

更好的解决方案是获取一个Twitter访问库,该库返回有意义的状态消息,并且可以处理自己的重试。

修改

到目前为止,最有用的一行是statusCode = con.getResponseCode();,它为您提供了一个可以对Twitter's Error Codes list进行检查的值。一般来说,如果你得到2xx,你的请求已成功,4xx意味着你的代码做错了,5xx意味着Twitter做错了。至少可以让你调整你的错误信息,如果你 - 你可能应该 - 纾困而不是试图解决它。

看起来420和429最好表明你可以重试。但是,除了在无限循环中重复您的请求之外,您还需要更加谨慎。您一定要阅读Rate Limits文档以获取指导。