即使 OkHttp 不是依赖项,OkHttp 连接泄漏日志行
Posted
技术标签:
【中文标题】即使 OkHttp 不是依赖项,OkHttp 连接泄漏日志行【英文标题】:OkHttp connection leak log line even when OkHttp is not a dependency 【发布时间】:2018-05-19 20:21:18 【问题描述】:当我使用我的应用程序时,我在 Logcat 中不断看到以下日志行:
19098-19147/<package> W/OkHttpClient: A connection to <my server> was leaked. Did you forget to close a response body?
我对这个错误进行了一些研究,发现当你忘记关闭拦截器中的响应体时,它可能会发生。我注释掉了所有拦截器,看看其中一个是否导致了这个问题,但我仍然看到了日志行。我最终注释掉了 OkHttp 的所有用途,但我仍然以某种方式得到了错误。我什至从我的 Gradle 文件中删除了所有 OkHttp 依赖项,并添加了一个明确的行以确保它被排除为传递依赖项。我运行了 gradle app:dependencies 来生成我的依赖树,这样我就可以确保没有包含 OkHttp。不知何故,我仍然看到这条日志行。我不明白这怎么可能。
有没有人知道任何常见的库可能已经将此日志行从 OkHttp 库复制并粘贴到他们的库中?我搜索了我的其他依赖项的所有源代码,但没有在其中任何一个中找到类似的日志行。
这可能与 android Studio 注入的新分析代码有关吗? See this article for more information.
更新:原来我的 Fresco 依赖一定是使用了系统提供的 OkHttp 或类似的东西。 @Selvin 评论说 Android 在内部使用它。无论如何,显然当 Fresco 在尝试加载图像时收到带有错误的 HTTP 响应(在我的情况下为 HTTP 响应代码 401),它会记录此错误。我没有看到任何使用 Fresco/OkHttp 处理 HTTP 错误的好方法。我用 Fresco 打开了以下问题:HTTP error response when loading image results in leaked connection #1983
【问题讨论】:
OkHttp 用作内部 http 客户端(作为 aosp 的一部分) 【参考方案1】:我知道这是很晚的回应,但也许有人仍然对这个问题感到疯狂,最后我发现了发生了什么。是的:OkHttp 从 Android 4.4 开始在 HttpURLConnection/HttpsURLConnection 组件内部使用,因此即使您没有在项目中直接使用 OkHttp 库,您也可以在 logcat 中获取这些无聊的消息。
问题是由2个因素产生的:
-
套接字被 urlConnection 对象重用,试图
优化同一主机上多个请求的性能。
响应流未正确关闭(见下文如何解决)
为了防止出现这些日志行或只是对流程进行更多控制,我对代码进行了一些更改并最终解决了这个问题。
我禁用了持久连接设置Connection: close
标头。默认为Connection: keep-alive
在阅读响应的内容(正文)之前,请检查 http 响应代码。正如in this article 所描述的,如果响应代码 >= 400,您将失败:您不必读取连接 InputStream getInputStream()
,而是读取 ErrorStream getErrorStream()
并通过在右侧流上调用 .close()
方法来关闭它。连接泄漏在这里。最后记得disconnect()
urlConnection 对象。
【讨论】:
以上是关于即使 OkHttp 不是依赖项,OkHttp 连接泄漏日志行的主要内容,如果未能解决你的问题,请参考以下文章
未找到功能性渠道服务提供者。尝试添加对 grpc-okhttp、grpc-netty 或 grpc-netty-shaded 工件的依赖项
OkHttpAndroid 项目导入 OkHttp ( 配置依赖 | 配置 networkSecurityConfig | 配置 ViewBinding | 代码示例 )