Sudarshan Sudarshan - 1 month ago 15
Android Question

Try-with-resources requires API level 19 (OkHttp)

I am trying to get web server response with OkHttp.
My current

minSdkVersion 15
.

My code is

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


And

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();
}
}


I am getting a warning at the line
try (Response response = client.newCall(request).execute())
.

It's saying "
Try-with-resources requires API level 19 (current min is 15)
.

I know that if I change the minimum API level to 19, it'll work fine. But I have to support min 15 API level.

Is there any solution?

Answer

The solution is to not use try-with-resources unless you can set your min API level to 19. So instead of this:

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

you should to this:

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

EDIT: The Java Language Specification, Section 14.20.3.1 provides a slightly different (but, in this case, functionally identical) equivalent to a basic try-with-resources statement (one without any catch or finally blocks) like you have:

{
    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();
            }
        }
    }
}

This has two effects. First, it makes the response variable local to the equivalent block. (My suggestion made it visible after the try statement finishes, which may be undesirable.) More importantly, it has the effect of suppressing any exception thrown while closing the resource. That is, if the body of the original try block throws an exception, invoking code will see that instead of the exception thrown by the close(). (The exception thrown by the close() would still be available via the getSuppressed() method of the exception actually thrown.) You don't need this more complicated version because (as far as I can tell from the API docs) Response.close() doesn't throw exceptions.

Comments