尝试使用资源需要API级别19(OkHttp)

时间:2016-11-03 18:18:25

标签: android json okhttp

我正在尝试使用OkHttp获取Web服务器响应。 我目前的minSdkVersion 15

我的代码是

    @Override
    protected String doInBackground(String... strings) {

        GetDataFromUrl getData = new GetDataFromUrl();
        String response = null;
        try {
                response = getData.run(URL);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return response;
    }

String run(String url) throws IOException {
Request request = new Request.Builder()
                .url(url)
                .build();

        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

我在第try (Response response = client.newCall(request).execute())行收到警告。

它说“Try-with-resources requires API level 19 (current min is 15)

我知道如果我将最低API级别更改为19,它将正常工作。但我必须支持min 15 API级别。

有没有解决方案?

2 个答案:

答案 0 :(得分:9)

对于未来的读者。

现在,有Java 8.您只需指定使用Java 8在gradle中编译

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

警告将消失。编译器会将代码转换为答案中的Ted Hopp。

答案 1 :(得分:8)

解决方案是不使用try-with-resources,除非你可以将你的最低API级别设置为19.所以不要这样:

try (Response response = client.newCall(request).execute()) {
    return response.body().string();
}

你应该这样:

Response response = null;
try {
    response = client.newCall(request).execute();
    return response.body().string();
} finally {
    if (response != null) {
        response.close();
    }
}

编辑:Java Language Specification, Section 14.20.3.1提供了与基本的try-with-resources语句(一个没有catchfinally的语句略有不同(但在这种情况下功能完全相同)块)你喜欢:

{
    final Response response = client.newCall(request).execute();
    Throwable primaryExc = null;

    try {
        return response.body().string();
    } catch (Throwable t) {
        primaryExc = t;
        throw t;
    } finally {
        if (response != null) {
            if (primaryExc != null) {
                try {
                    response.close();
                } catch (Throwable suppressed) {
                    primaryExc.addSuppressed(suppressed);
                }
            } else {
                response.close();
            }
        }
    }
}

这有两个影响。首先,它使response变量在等效块的本地变量。 (我的建议在try语句结束后可见,这可能是不可取的。)更重要的是,它具有抑制关闭资源时抛出的任何异常的效果。也就是说,如果原始try块的主体抛出异常,则调用代码将看到而不是close()抛出的异常。 (close()抛出的异常仍然可以通过实际抛出的异常的getSuppressed()方法获得。)你不需要这个更复杂的版本,因为(据我所知) API文档)Response.close()不会抛出异常。