【问题标题】:Do I need to call HttpURLConnection.disconnect after finish using it使用完毕后是否需要调用 HttpURLConnection.disconnect
【发布时间】:2012-06-15 18:14:42
【问题描述】:

以下代码基本上可以按预期工作。然而,偏执,我想,为了避免资源泄漏,

  1. 用完后需要打电话给HttpURLConnection.disconnect吗?
  2. 需要拨打InputStream.close吗?
  3. 需要拨打InputStreamReader.close吗?
  4. 在构建httpUrlConnection之后是否需要有以下2行代码:httpUrlConnection.setDoInput(true)httpUrlConnection.setDoOutput(false)

我之所以这么问,是因为我看到的大多数示例都没有进行此类清理。 http://www.exampledepot.com/egs/java.net/post.htmlhttp://www.vogella.com/articles/AndroidNetworking/article.html。我只是想确保这些示例也是正确的。


public static String getResponseBodyAsString(String request) {
    BufferedReader bufferedReader = null;
    try {
        URL url = new URL(request);
        HttpURLConnection httpUrlConnection = (HttpURLConnection)url.openConnection();
        InputStream inputStream = httpUrlConnection.getInputStream();
        bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        int charRead = 0;
        char[] buffer = new char[1024];
        StringBuffer stringBuffer = new StringBuffer();
        while ((charRead = bufferedReader.read(buffer)) > 0) {
            stringBuffer.append(buffer, 0, charRead);
        }
        return stringBuffer.toString();
    } catch (MalformedURLException e) {
        Log.e(TAG, "", e);
    } catch (IOException e) {
        Log.e(TAG, "", e);
    } finally {
        close(bufferedReader);
    }
    return null;
}

private static void close(Reader reader) {
    if (reader != null) {
        try {
            reader.close();
        } catch (IOException exp) {
            Log.e(TAG, "", exp);
        }
    }
}

【问题讨论】:

    标签: android


    【解决方案1】:

    是的,您需要先关闭输入流,然后再关闭 httpconnection。根据javadoc

    每个 HttpURLConnection 实例用于发出单个请求,但到 HTTP 服务器的底层网络连接可能会被其他实例透明地共享。在请求之后对 HttpURLConnection 的 InputStream 或 OutputStream 调用 close() 方法可能会释放与此实例关联的网络资源,但不会影响任何共享的持久连接。如果此时持久连接处于空闲状态,则调用 disconnect() 方法可能会关闭底层套接字。

    接下来两个问题的答案取决于您的连接目的。阅读此link 了解更多详情。

    【讨论】:

    • 谢谢。您认为上面给出的两个教程链接没有调用断开连接有错误吗?或者,我错过了什么?
    • 我并不是说这是一个错误。但是,断开连接是极端情况(套接字关闭打开操作代价高昂),除非你真的想要我不会去做。 stream.close() 释放大部分网络资源,应该足够了。同样,如果您的要求是可以每次都创建套接字,那么调用断开连接没有任何问题。
    • 我将继续频繁地向几乎相同的服务器发出请求,内存泄漏是我唯一关心的问题。如果我正确理解了文档,就我而言,不需要调用 disconnect。
    • 使用 Android 4.4,在将信号数据流式传输到 Jetty 8.1.11 Servlet-Container 并在关闭输出流编写器后断开 HttpUrlConnection 时,我得到一个 org.eclipse.jetty.io.EofException: early EOF 异常。当我删除对disconnect 的调用并仅关闭输出流时,异常消失了。 有人可以确认这种行为吗? 在 Android 4.2 上,它按预期工作,关闭流并断开 HttpUrlConnection
    • 根据the docs,你应该调用disconnect,并且他们没有关闭示例中的输入流,这表明disconnect为你做了。
    【解决方案2】:

    我相信调用 setDoInput() 或 setDoOutput() 的要求是确保在向连接上的流写入或读取任何内容之前调用它们。除此之外,我不确定何时调用这些方法是否重要。

    【讨论】:

      猜你喜欢
      • 2011-03-15
      • 1970-01-01
      • 2011-04-09
      • 2013-08-29
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多