Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android StrictMode Throwable: Explicit termination method 'end' not called

Tags:

android

I'm seeing a StrictMode failure, and I can't see what's wrong with what I'm doing. The failure is:

java.lang.Throwable: Explicit termination method 'end' not called
    E/StrictMode(26875):    at dalvik.system.CloseGuard.open(CloseGuard.java:184)
    E/StrictMode(26875):    at java.util.zip.Inflater.<init>(Inflater.java:82)
    E/StrictMode(26875):    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:96)
    E/StrictMode(26875):    at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:81)
    E/StrictMode(26875):    at libcore.net.http.HttpEngine.initContentStream(HttpEngine.java:528)
    E/StrictMode(26875):    at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:836)
    E/StrictMode(26875):    at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
    E/StrictMode(26875):    at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
    E/StrictMode(26875):    at com.mycompany.MyClass.sendJson(MyClass.java:267)

I configure StrictMode:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
              .detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog()
                    .penaltyDeath().build());
}

The code looks something like the following:

HttpURLConnection connection = null;
OutputStream outputStream = null;
InputStream in = null;

try {
        connection = (HttpURLConnection)new URL("http://our.server/some/path").openConnection();

        connection.setRequestProperty("Accept", "application/json");
        connection
                .setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setDoOutput(true);

        outputStream = connection.getOutputStream();

        String content = "{\"some\":\"json data\"}";
        byte bytes[] = content.getBytes("UTF-8");
        outputStream.write(bytes);
        outputStream.flush();

        responseCode = connection.getResponseCode(); // This is line 267 in the stack trace

        if (HttpURLConnection.HTTP_OK == responseCode
                || HttpURLConnection.HTTP_CREATED == responseCode) {

            // do something with a successful response
        }
    }

} catch (IOException e) {
    // report the exception
} finally {
    if (null != connection) {
        connection.disconnect();
    }
    if (null != outputStream) {
        try {
            outputStream.close();
        } catch (IOException e) {
        }
    }
    if (null != in) {
        try {
            in.close();
        } catch (IOException e) {
        }
    }
}

I found somebody complaining of seeing the same StrictMode failure when using Google AdMob SDK (https://groups.google.com/forum/?fromgroups=#!topic/google-admob-ads-sdk/yVss4ufdPp4) but I've not been able to find any solution so far.

like image 246
Jonathan Caryl Avatar asked Apr 03 '13 14:04

Jonathan Caryl


2 Answers

What happens if you get the response stream, read it completely and close it (even if the response code is not OK).
I think this will invoke HttpEngine.release(), and thus avoid the exception when the GzipInputStream is later finalized (as the exception is prepared in the constructor but throwed in finalize())

like image 91
bwt Avatar answered Sep 28 '22 01:09

bwt


I think connection.getResponseCode() opens an input stream. So you will need to retrieve the input stream and close it.

like image 21
tidbeck Avatar answered Sep 28 '22 00:09

tidbeck