原文(需翻墙):Android’s HTTP Clients 2011年 源至 http://android-developers.blogspot.jp/
Most network-connected Android apps will use HTTP to send and receive data.Android includes two HTTP clients: HttpURLConnection and Apache HTTP Client. Both support HTTPS, streaming uploads and downloads, configurable timeouts, IPv6 and connection pooling(集中;混合存储).
Apache HTTP Client
DefaultHttpClient and its sibling(姊妹;同族) AndroidHttpClient are extensible HTTP clients suitable for web browsers. They have large and flexible(灵活) APIs. Their implementation is stable and they have few bugs.
But the large size of this API makes it difficult for us to improve it without breaking compatibility(兼容性). The Android team is not actively working on Apache HTTP Client.
HttpURLConnection
HttpURLConnection is a general-purpose, lightweight HTTP client suitable for most applications. This class has humble(卑微的) beginnings, but its focused API has made it easy for us to improve steadily(稳定地).
Prior toFroyo(2.2), HttpURLConnection had some frustrating( 令人沮丧) bugs. In particular, calling close()
on a readable InputStream could poison(污染;毒) the connection pool. Work around this by disabling connection pooling:
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");
}
}
InGingerbread(2.3), we added transparent response compression(压缩). HttpURLConnection will automatically add this header to outgoing(友好) requests, and handle the corresponding response:
Accept-Encoding: gzip
Take advantage of this by configuring your Web server to compress responses for clients that can support it. If response compression is problematic(有问题), the class documentation shows how to disable it.
Since HTTP’s Content-Length
header returns the compressed size, it is an error to use getContentLength() to size buffers for the uncompressed data. Instead, read bytes from the response until InputStream.read() returns -1.
We also made several improvements to HTTPS in Gingerbread. HttpsURLConnection attempts to connect with Server Name Indication (SNI) which allows multiple HTTPS hosts to share an IP address. It also enables compression and session tickets. Should the connection fail, it is automatically retried without these features. This makes HttpsURLConnection efficient(能干;有效率) when connecting to up-to-date servers, without breaking compatibility(兼容性) with older ones.
InIce Cream Sandwich(4.0), we are adding a response cache. With the cache installed, HTTP requests will be satisfied in one of three ways:
-
Fully cached responses are served directly from local storage. Because no network connection needs to be made such responses are available immediately.
-
Conditionally cached responses must have their freshness validated by the webserver. The client sends a request like “Give me /foo.png if it changed since yesterday” and the server replies with either the updated content or a
304 Not Modified
status. If the content is unchanged it will not be downloaded! -
Uncached responses are served from the web. These responses will get stored in the response cache for later.
Use reflection(反射机制) to enable HTTP response caching on devices that support it. This sample code will turn on the response cache on Ice Cream Sandwich without affecting earlier releases:
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) {
}
}
You should also configure your Web server to set cache headers on its HTTP responses.
Which client is best?
Apache HTTP client has fewer bugs onEclair(2.0) andFroyo(2.2). It is the best choice for these releases.
For Gingerbread(2.3)and better, HttpURLConnection is the best choice. Its simple API and small size makes it great fit for Android. Transparent compression and response caching reduce network use, improve speed and save battery. New applications should use HttpURLConnection; it is where we will be spending our energy going forward.
译文:AndroidHttp通信 HTTP Client与HttpURLConnection的区别
Apache HTTP Client
DefaultHttpClient 以及其相关类 AndroidHttpClient 适用于 web browsers, 他们是可扩展的,并且拥有大量的稳定APIs。
但是,在不破坏其兼容性的前提下很难对如此多的APIs做修改。因此,Android 团队对修改优化Apache HTTP Client表现的并不积极。
HttpURLConnect
HttpURLConnect 是一个通用的、适合大多数应用的轻量级组件。这个类起步比较晚,很容易在主要API上做稳步的改善。
HttpURLConnection在Froyo上存在一些bug,尤其是在读取 InputStream时调用 close()方法。解决这个bug,可参考如下代码:
- 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的报文头中添加了对报文的压缩处理,包括请求报文和回复报文。
- Accept-Encoding: gzip
Web服务器加上这个配置就可以支持报文的压缩,如果响应时的压缩产生问题,可参考doc文档关闭这个功能。
HTTP的头信息的Content-Length返回的是压缩后的大小,使用getContentLength()返回未压缩字节的大小。因此从响应数据读取字节直到 InputStream.read()返回-1,这样可以获取响应数据的大小。
GingerBread的HTTPS也做了几项改进,HttpsURLConnection能够连接支持多个HTTPS主机共享一个IP 的服务器Server Name Indication(SNI)。它支持压缩和session,如果连接失败,他会取消压缩和session属性自动重连。这样保证了HttpsURLConnection在支持老版本的前提下支持新的服务器。
在Ice Cream Sandwich中,增加了缓存机制,使用缓存,HTTP requests需要满足一下三种方式之一。
1、没有网络连接时使用本地缓存获取响应。
2、比如,获取一张图片,客户端发起请求,如果服务端没有修改,则使用缓存数据。
3、没有及时的获取到响应数据,可以使用缓存。
如果想使用早期的Android版本支持缓存,可以使用Java的反射机制。代码如下:
- 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服务器支持缓存属性。