【问题标题】:Android StrictMode Throwable: Explicit termination method 'end' not calledAndroid StrictMode Throwable:未调用显式终止方法“end”
【发布时间】:2013-04-03 14:12:34
【问题描述】:

我看到 StrictMode 失败,我看不出我正在做的事情有什么问题。失败是:

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)

我配置了 StrictMode:

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

代码如下所示:

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

我发现有人抱怨在使用 Google AdMob SDK (https://groups.google.com/forum/?fromgroups=#!topic/google-admob-ads-sdk/yVss4ufdPp4) 时遇到同样的 StrictMode 失败,但到目前为止我还没有找到任何解决方案。

【问题讨论】:

  • 尝试(在 gzip 后的 HTTP 响应上),但无法重现异常。您是否设置了明确的StrictMode policy?您的 Android SDK 版本是多少?
  • 我已编辑问题以显示我如何配置 StrictMode
  • 您找到解决方案了吗?对我来说,这看起来像是 Android 的 GZIPInputStream 中的一个错误,因为它创建了一个 Inflater,为“end”注册了一个密切的保护,但实际上从未调用 end。
  • 我还没有开始尝试 bwt 的解决方案,主要是因为我们正在与之交谈的服务器已经更新,而且我现在总是得到 HTTP_OKs,所以泄漏的代码路径不是被触发。但这对我来说似乎是一个错误,我同意。

标签: android


【解决方案1】:

如果您获得响应流、完整阅读并关闭它(即使响应代码不正确)会发生什么。
我认为这将调用HttpEngine.release(),从而避免在稍后完成GzipInputStream 时出现异常(因为异常在构造函数中准备好但在finalize() 中抛出)

【讨论】:

  • 这看起来很有希望,但它对我不起作用,与乔纳森类似。在 Nexus S 上使用 4.1.2 测试。
【解决方案2】:

我认为connection.getResponseCode() 打开了一个输入流。所以你需要检索输入流并关闭它。

【讨论】:

  • 这解决了我类似的 StrictMode 问题!谢谢!!代码sn-p:connection.getInputStream().close()
  • @PaniniLuncher 感谢它对我有用。由于connection.getContentLength(),我得到了类似的结果。这个。
猜你喜欢
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 2018-05-26
相关资源
最近更新 更多