bitmapfun项目 看到一个函数[在使用HttpURLConnection下载之前调用]:
/**
* Workaround for bug pre-Froyo, see here for more info:
* http://android-developers.blogspot.com/2011/09/androids-http-clients.html
*/
public static void disableConnectionReuseIfNecessary() {
// HTTP connection reuse which was buggy pre-froyo
if (hasHttpConnectionBug()) {
System.setProperty("http.keepAlive", "false");
}
}
/**
* Check if OS version has a http URLConnection bug. See here for more information:
* http://android-developers.blogspot.com/2011/09/androids-http-clients.html
*
* @return
*/
public static boolean hasHttpConnectionBug() {
return Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO;
}
大多数需要网络连接的Android应用都会使用HTTP来传输数据。Android自带了两个HTTP客户端:HttpURLConnection和Apache HTTP Clinent。它们都支持HTTPS,文件上传下载,配置超时,IPV6及连接池。
DefaultHttpClient 及其相似的 AndroidHttpClient 都是HttpClient的扩展适用于Web浏览器。它们有丰富的可扩展的API,同时也很稳定没有什么Bug。但是这里重量级的API让我们难以修改后保证它的兼容性,因为Android团队并没有负责Apache HTTP Client 的开发和维护!
HttpURLConnection
HttpURLConnection是一个通用的,轻量级的适用于绝大多数应用的HTTP客户端。这个类比较底层,但我们可以很容易的稳步修改它的关键的API。
在Froyo(2.2)之前,HttpURLConnection有几个烦人的Bug,特别是,在一个可读的InputStream中调用close()会
污染连接池,一个解决方案就是在低android版本中禁用连接池。
private void disableConnectionReuseIfNecessary() { // HTTP connection reuse which was buggy pre-froyo if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) { System.setProperty("http.keepAlive", "false"); } }
Accept-Encoding: gzip
如果你发现服务器返回的压缩数据有问题,可以参考HttpURLConnection的文档来禁用该功能!
因为HTTP客户端的Content-Length头部返回的是压缩后的大小,所以使用getContentLength()来获得解压后的数据块的大小是错误的。你应该从响应中读取字节直到InputStream.read()返回-1。
同时我们对在Gingerbread中的HTTPS连接做了一些优化,当HttpsURLConnection尝试连接SNI(Server Name Indication)将允许多个hosts共享一个IP地址。同样支持压缩和Session tickets。如果连接失败,将自动重试(it is automatically retried without these features)。这使得HttpURLConnection在连接新的服务器时更有效,同时不破坏向下兼容。
在Ice Cream Sandwich(4.X)中,我们添加了响应缓存。有了缓存,HTTP请求就会满足下面三种方式:
(1)完全缓存的响应将直接从本地存在中获得。因为无需进行网络连接 ,这样的响应可以马上获得。
(2)条件缓存的响应必须到服务器验证是否过期,客户端发送一个请求如"给我 /foo.png 如果从昨天后发生了改变的话",然后服务器响应返回更新的内容 或者一个304 Not Modified状态。如果内容没有更新,则将不会下载 。
(3)非缓存的响应将从web端获得,这些请求会存储在响应缓存中以务后用。
可以利用反射来在支持的设备中开启HTTP 响应缓存 。下面的代码将在4.0之后的版本的开启响应缓存 。而不会影响之前的版本。
private void enableHttpResponseCache() { try { long httpCacheSize = 10 * 1024 * 1024; // 10 MiB File httpCacheDir = new File(getCacheDir(), "http"); Class.forName("android.net.http.HttpResponseCache") .getMethod("install", File.class, long.class) .invoke(null, httpCacheDir, httpCacheSize); } catch (Exception httpResponseCacheNotAvailable) { } }
哪一个客户端最好?
在Eclair(2.1)和Froyo(2.2)中,Apache HTTP Client(相比HttpURLConnection)没有什么Bug,
对于这些发行版,它是最好的选择。
对于 Gingerbread(2.3)及之后的版本。HttpURLConnection是最好的选择。它的简单轻量最适合android。
压缩,缓存响应以减少网络连接,提升速度,省电,新的应用应该使用HttpURLConnection,它也是我们将来的着力点。