最近在看 Volley 的源码,发现里面的网络请求方式很有意思,在 Android 2.3 及以上用的是 HttpURLConnection,2.2 及以下用的是 HttpClient。秉着好奇心找到一篇有关的文章,于是便尝试着翻译下来,第一次翻译文章,有什么不足的地方,麻烦指出。
大部分需要联网的 Android 应用程序都会使用 HTTP 去发送和接收数据。Android 中包括两种方式来进行 HTTP 的请求:HttpURLConnection 和 HttpClient。两种方式都支持 HTTPS、数据流上传和下载、配置超时时间、Ipv6 和连接池。
DefaultHttpClient 和它同级的 AndroidHttpClient 都是很适合 web 浏览器的可拓展的 HTTP 客户端。他们有着众多的 API 而且十分灵活,同时也十分的稳定,极少有 bug。
但是由于 API 的数量过多,使得我们很难在不破坏兼容性的情况下对其进行拓展。而且 Android 团队对于 HttpClient 也不是很积极。
HttpURLConnection 是一个适用于大多数应用程序的、通用的轻量级 HTTP 客户端。它提供的 API 比较简单,但它主要的 API 使我们能轻易的使用和拓展它。
在 Android 2.2 之前,HttpURLConnection 有着很多让人厌烦的 bug。特别是,在一个可读的 InputStream 中调用 close() 方法能让连接池失效。我们可以通过禁用连接池来解决这个问题:
private void disableConnectionReuseIfNecessary () {
// HTTP 连接重用,这是 Android 2.2 之前的一个 bug
if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
System.setProperty("http.keepAlive", "false");
}
}
在 Android 2.3,我们添加了透明的响应缓存。HttpURLConnection 将会自动在每个发出的请求中加入消息头,以及处理相应的返回结果:「Accept - Encoding:gzip」
通过配置你的 Web 服务器来支持对客户端的响应结果进行压缩的功能,从而获取最大的好处。如果响应压缩有问题,这篇文档 将显示如何禁用它。
自从 HTTP 的请求头 content-Length 返回压缩的大小之后,使用 getContentLength() 来作为未压缩数据的缓冲区是错误的。而应该从响应中读取字节,直到 InputStream.read() 返回 -1。
我们而在 Android 2.3 中为 HTTPS 做了很多的改进。HttpsURLConnection 尝试连接服务器名称指示(SNI),允许多个 HTTPS 主机共享一个 IP 地址,同时也启用了压缩和会话机制。如果连接失败了,它会自动去重新连接。这使得 HttpsURLConnection 在连接到最新服务器时更加有效,而且并不会破坏旧版服务器的兼容性。
在 Android 4.0,我们可以添加一个响应缓存。当缓存被安装之后,HTTP 请求都会同时满足这三种情况:
使用反射在支持它的设备上启用 HTTP 的响应缓存。示例代码将会打开 Android 4.0 的响应缓存,而不会影响早期的版本。
private void enableHttpResponseCache(){
long httpCacheSize = 10 * 1024 * 1024; // 10 MB
File httpCacheDir = new File(getCacheDir(), "http");
try {
Class.forName("android.net.http.httpResoonseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
你应该配置你的 Web 服务器来在它的 HTTP 响应中设置缓存的消息头。
HttpClient 在 Android 2.2 之前拥有比较少的 bug,因此选择它是最好的选择。
在 Android 2.3 及以后,HttpURLConnection 是最好的选择。它那简单的 API 以及小尺寸使其非常适合 Android。透明的压缩和响应缓存减少了网络的使用,提高速度以及节省电量。新的应用程序中应使用 HttpURLConnection。我们未来也会将更多的精力花在优化 HttpURLConnection 上面。