大多数联网类Android apps将使用HTTP来发送和接收数据。Android包含两种HTTP客户端:HttpURLConnection和Apache HTTP Client。它们两者都支持HTTPS,streaming上传和下载,可配置的超时,IPv6和连接池。
Apache HTTP Client
DefaultHttpClient 和它的兄弟AndroidHttpClient是适用于web浏览器的可扩展的HTTP clients。它们具有数量众多且灵活的APIs。它们的实现是稳定的,并具有很少的bugs。
但是这个API的大小使得在不破坏兼容性的情况下提升它变得非常困难。Android团队在Apache HTTP Client上面没有活跃的开发。
HttpURLConnection
是一个通用的,轻量级的HTTP client,它适用于大多数应用。这个类具有简陋的初始版本,但它的集中的API使得我们稳定地提升它比较简单。
在Froyo之前,HttpURLConnection具有一些令人困扰的bugs。特别的,在一个可读的InputStream上调用close()可能会污染连接池。可以通过禁用连接池来绕过这一点:
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");
}
}
在Gingerbread上,我们添加了透明的响应压缩。HttpURLConnection将会自动地把这个header添加到outgoing requests,并处理对应的响应:
Accept-Encoding: gzip
通过配置你的Web server来压缩响应,以使支持它的客户端能充分利用这一点。如果响应压缩出问题了,class documentation显示了如何禁用它。
由于HTTP的Content-Length header返回了压缩后的大小,因而使用getContentLength()来为加压后的数据确定buffers的大小是不正确的。相反,应该从response中读取bytes,直到InputStream.read()返回-1。
在Gingerbread中,我们也对HTTPS做了一些提升。HttpsURLConnection尝试去连接Server Name Indication (SNI),其允许多个HTTPS主机共享一个IP地址。它也能够启用压缩和session tickets。如果连接失败,它会自动地在没有这些功能的情况下重试。这使得HttpsURLConnection在连接到up-to-date服务器时很高效,而又不会老版本的兼容性。
在Ice Cream Sandwich中,我们添加了一个响应cache。通过安装这个cache,HTTP请求将由三种方式中的一种来满足:
完全缓存的响应直接有本地存储器来提供服务。由于不需要连接网络,这种响应是立即可用的。
有条件地缓存的响应必须具有它们webserver的刷新验证。客户端发送一个诸如“Give me /foo.png if it changed since yesterday”的请求,服务器用更新后的内容或一个304 Not Modified状态来回应。如果内容没有改变,它将不会被下载!
未缓存的响应由web服务器来服务。这些响应稍后会被存入响应缓存中。
使用反射来在支持它的设备上启用HTTP 响应缓存。这段示例代码将会在不影响早期版本的情况下在Ice Cream Sandwich上打开响应缓存:
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) {
}
}
你也应该配置你的Web服务器来在它的HTTP响应中设置cache headers。
那个client是最好的?
Apache HTTP client在Eclair和Froyo上具有更少的bugs。对于这些版本它是最好的选择。
Gingerbread和更新的版本,HttpURLConnection是最好的选择。它的简单的API和很小的大小使得它很适用于Android。透明的压缩和响应缓存减少了网络使用,提升了速度并节省了电量。新的应用应该使用HttpURLConnection;那也是我们将会耗费大量精力来提升的东西。
译自: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
Done.