[HttpURLConnection的OkHttpClient连接泄漏警告

问题描述 投票:3回答:1

我正在使用HttpURLConnection从服务器检索某些配置。它工作正常,但由于某种原因,我在logcat中收到以下警告:

OkHttpClient:与...的连接已泄漏。您是否忘了关闭响应主体?

[在this问题中指出,Android在OkHttp内部使用HttpUrlConnection。我要怎么引起这个警告?

这是我正在使用的代码:

    HttpURLConnection connection = null;
    OutputStream outputStream = null;
    String result;
    try {
        URL url = new URL(CONFIG_URL);
        connection = (HttpURLConnection) url.openConnection();
        connection.setReadTimeout(READ_TIMEOUT_MILLI);
        connection.setConnectTimeout(CONNECT_TIMEOUT_MILLI);
        connection.setRequestMethod(REQUEST_METHOD);

        connection.setDoInput(true);

        connection.addRequestProperty("Content-Type", "application/json");
        connection.addRequestProperty("Accept", "application/json");

        outputStream = connection.getOutputStream();
        try (DataOutputStream wr = new DataOutputStream(outputStream)) {
            wr.write(data.toString().getBytes(STRING_ENCODING));
            wr.flush();
            wr.close();

            int responseCode = connection.getResponseCode();

            if (responseCode != HttpsURLConnection.HTTP_OK) {
                Log.e(TAG, "HTTP error code: " + responseCode);
                return;
            }

            try (InputStream stream = connection.getInputStream()) {
                if (stream != null) {
                    result = readStream(stream, READ_STREAM_MAX_LENGTH_CHARS);
                    //...
                    connection.disconnect();
                }
            } catch (Throwable e) {
                Log.e(TAG, "run: failed to parse server response: " +e.getMessage());
            }
        }
    } catch (Exception e) {
        Log.e(TAG, "HttpSendTask: failed to send configuration request " + data +": " +e.getMessage());
    } finally {
        if (outputStream != null) {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            connection.disconnect();
        }
    }
android networking httpurlconnection okhttp
1个回答
0
投票

我知道这是很晚的回复,但也许有人仍然对此问题感到疯狂,最后我才知道发生了什么。是的:从Android 4.4开始,OkHttp在HttpURLConnection / HttpsURLConnection组件内部使用,因此即使您没有在项目中直接使用OkHttp库,也可以在logcat中获取这些无聊的消息。

该问题由两个因素产生:

  1. 套接字被urlConnection对象重用,试图在同一主机上的多个请求上优化性能。
  2. 响应流未正确关闭(请参阅下面的解决方法)

为了防止出现这些日志行或仅对流程进行更多控制,我对代码进行了一些更改,并最终解决了此问题

  • 我禁用了设置Connection: close标头的持久连接。默认值为Connection: keep-alive
  • 在读取响应的内容(正文)之前,请检查http响应代码。如in this article所述,如果响应代码> = 400,您将失败:您不必读取InputStream getInputStream()连接,而是读取ErrorStream getErrorStream()并通过在右侧流上调用.close()方法将其关闭。连接泄漏在这里。最后记住disconnect() urlConnection对象。
© www.soinside.com 2019 - 2024. All rights reserved.