Android 上的持久 HttpURLConnections

Posted

技术标签:

【中文标题】Android 上的持久 HttpURLConnections【英文标题】:Persistent HttpURLConnections on Android 【发布时间】:2011-05-06 22:50:52 【问题描述】:

我在尝试让 android 应用程序(好吧,服务,它有任何区别)使用持久 HTTP 1.1 连接时遇到了问题。

以下循环(简化的测试用例)通过桌面 JRE 上的单个 TCP 会话工作,但在 Android 设备上会导致整个套接字创建/拆卸周期。

        while (true) 
            URL url;
            try 
                url = new URL("http://10.0.0.125:8080/SRV?");

                URLConnection connection = url.openConnection();

                HttpURLConnection httpConnection = (HttpURLConnection) connection;                  
                int responseCode = httpConnection.getResponseCode();

             catch (MalformedURLException e) 
             catch (IOException e) 
                   
        

Oracle 的 JDK 描述了一种叫做“系统属性”的东西:

http.keepAlive= 默认:真

http.maxConnections= 默认值:5

在 Android 的运行时中是否有类似的东西阻止保持持久连接?

【问题讨论】:

【参考方案1】:

Android 的 JVM 在底层使用 Apache HTTP 组件库进行 HTTP 连接(即使是使用 java.net 接口完成的连接):因此其行为与 Oracle JVM 略有不同。

理论上,底层的 Harmony 代码尊重 http.keepAlive 系统属性,但我不确定 Google 的副本是否保留了这种行为。

如果您想完全确定发生了什么,您必须使用 HttpComponents 代码。这是漫长而痛苦的,但是如果您查看http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html,它概述了http 组件的连接管理方法。查看第 2.11 节,其中详细介绍了如何使用 HTTP 组件显式控制连接管理。

祝你好运。

【讨论】:

作为一项快速测试,如果设置所需的标头可以解决问题,也可以尝试URLConnection.setRequestProperty("Connection", "keep-alive")。 感谢您指出正确的方向 - Google 文档对于 java.net 内部使用 Apache 的 HttpClient 这一事实并不是特别直截了当。我将使用 Apache 接口(以及 2.11 中提供的信息)重写我的代码,并会及时更新。 @harism - 它似乎没有改变任何东西。 @Femi - 尽管很奇怪,但使用 HttpClient 似乎尊重“http.keepAlive” - 也许翻译层以错误的方式设置了某些东西(并且不接受这样一个事实我已将系统属性从默认值更改) 这确实很奇怪。我从来没有尝试过明确设置 keepAlive 位,但你是对的:完全有可能一个人从裂缝中溜走。【参考方案2】:

我看到了相同的问题,即未建立持久的 HTTP 1.1 连接。我编写了一个快速测试应用程序以获取更多详细信息。

首先,我从我的应用程序中执行 TCP 流量转储,以查看发生了什么。 “Connection:keep-alive”正在正确发送到我的服务器。然后我的服务器响应“Connection:keep-alive”。然而,在我的应用关闭其连接的 InputStream 后,Android 也关闭了底层套接字......而不是被持久化。

为了更深入地挖掘,我编写了我的应用程序以使用两种不同的方法进行连接:

HttpURLConnection con = (HttpURLConnection) url.openConnection();

HttpClient 客户端 = new DefaultHttpClient();

事实证明,HttpClient 并没有持久化底层套接字,但 HttpURLConnection 可以。因此,如果您想要获得最佳性能,请使用 HttpURLConnections,直到 Android 解决 DefaultHttpClient 中的此错误。

看起来像是 Android HTTP 1.1 实现中的一个错误?

【讨论】:

针对 Gingerbread 及更高版本的应用程序使用 HttpURLConnection。 developer.android.com/training/basics/network-ops/…

以上是关于Android 上的持久 HttpURLConnections的主要内容,如果未能解决你的问题,请参考以下文章

android端口号选择上的持久TCP连接?

Android 和 iOS 上的本地存储有多持久?

Android 将图片网址url转化为bitmap

Android 应用持久认证

Android KeyStore - 密钥并不总是持久的

Android网络请求框架AsyncHttpClient实例详解(配合JSON解析调用接口)