我需要在使用完HttpURLConnection后调用HttpURLConnection.disconnect吗?

31
以下代码基本上可以正常工作。然而,为了谨慎起见,我想知道以下几点,以避免资源泄漏:
  1. 在使用完后,我是否需要调用 HttpURLConnection.disconnect
  2. 是否需要调用 InputStream.close
  3. 是否需要调用 InputStreamReader.close
  4. 在构造 httpUrlConnection 后,我是否需要使用以下两行代码: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);
        }
    }
}
2个回答

25

根据javadoc,确实需要先关闭inputstream,然后再关闭httpconnection。

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

接下来两个问题的答案取决于您的连接目的。请阅读此链接以获取更多详细信息。


谢谢。您认为上面给出的两个教程链接中是否存在错误,因为它们没有调用disconnect吗?或者,是我漏掉了什么? - Cheok Yan Cheng
2
我不是说这是一个错误。但是,断开连接是极端情况(套接字关闭打开操作很昂贵),除非你真的想要,否则我不会选择它。stream.close() 释放大部分网络资源应该足够了。同样,如果您的需求允许每次创建套接字,那么调用disconnect也没有问题。 - kosa
我将频繁向几乎相同的服务器发出请求,并且内存泄漏是我唯一关心的问题。如果我正确理解了文档,那么在我的情况下没有必要调用断开连接。 - Cheok Yan Cheng
1
在使用Android 4.4时,我将信号数据流传输到Jetty 8.1.11 Servlet-Container并在关闭输出流写入器后断开HttpUrlConnection时,会出现org.eclipse.jetty.io.EofException: early EOF异常。当我删除对disconnect的调用并仅关闭输出流时,该异常消失。有人可以确认这种行为吗? 在Android 4.2上,关闭流和断开HttpUrlConnection按预期工作。 - Sebastian S.
根据文档所述,您应该调用disconnect方法,并且在示例中他们没有关闭输入流,这表明disconnect方法会为您完成这个操作。 - Peppe L-G
是的,但如果你不关闭它呢?它会自动超时吗? - john k

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接