[Android Pro] 关于Android的HTTP客户端的小秘密

简介:

原文:http://android-developers.blogspot.com/2011/09/androids-http-clients.html

译文:http://yunfeng.sinaapp.com/?p=196

转载自:http://blog.csdn.net/forever_crying/article/details/7021174

我是转载者.

据Android Dalvik团队的Jesse Wilson 同学讲, 在Android系统中可以使用两种HTTP客户端来收发HTTP数据.

一个就是大名鼎鼎的Apache HTTP Client, 而另外一个就是 HttpURLConnection.

Apache HTTP Client

DefaultHttpClient 和她的兄弟 AndroidHttpClient 是用于浏览器的及具扩展性的HTTP客户端. 他们都有很多APIs. 他们的实现都很可靠并且只有很少的BUGs.

因为已经有了一票APIs的存在, 所以Dalvik团队的同学们想要改进这个客户端并且不破坏其兼容性的情况下是非常非常困难滴! 并且Android团队的同学们也并没有负责Apache HTTP Client 的开发和维护!

HTTP URL Connection

而 HttpURLConnection 就不一样了, 这家伙是通用的 轻量级的一个HTTP客户端实现,对于大多数App来说都是够用的. 这家伙功能简洁并且很容易的增强其功能.

在 Froyo 发布以前, HttpURLConnection 有一些非人让人郁闷的BUGs . 最郁闷的是, 当你在可读取的InputStream上调用 close()函数的时候会 污染连接池 (connection pool).  可以通过禁用连接池的方法还解决这个问题:

    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这个版本中, Dalvik团队的同学又添加了自动压缩数据的功能. 当你调用HttpURLConnection的时候,她回自动的偷偷的添加gzip属性到请求头中,并且会自己解压返回的数据, 开发者完全不用为了处理压缩数据而增加工作量, 只要服务器支持gzip就ok啦:

Accept-Encoding: gzip

如果你发现服务器返回的压缩数据有问题,可以参考该类的doc文档来看看如何禁用该功能!

由于Content-Length返回的是压缩后的数据长度,所以使用 getContentLength() 函数得到的Buffer数据大小是不正确的哦! 你要使用从响应中一直读取字节流直到InputStream.read()函数返回-1为止.

在Gingerbread版本中,同样也增强了HTTPs的功能. HttpsURLConnection尝试和Server Name Indication (SNI)连接,这样多个HTTPs主机可以共享同一个IP地址. 同样支持压缩和session tickets. 如果连接失败,她会自动禁用这些功能去重新连接.

而在 Ice Cream Sandwich版本中,Dalvik团队的同学又不安分了, 继续添加了一些新的特性: 响应缓存(response cache) . 如果使用了缓存,那么HTTP请求会有3种情况:

  • 完全缓存的结果将直接从本地缓存中返回,省去了联网访问服务器的过程, 在中国的龟速移动网络环境中很有用哦
  • 有条件(期限)的缓存将通过服务器来判断,客户端将发送这样一个请求”如果昨天得到的/foo.png这个图片已经更新了的话,就返回给我一个新的图片”,如果服务器更新了图片就返回新的数据 如果没有更新则返回”304 Not Modified ”.对于没有更新的内容就节约了流量.
  • 对于没有缓存过的内容就直接请求服务器的数据,然后把这个结果再放到缓存中去.
如果您想在Ice Cream Sandwich版本中使用缓存这个有用的功能,而又不想在其他版本的系统中导致程序Crash 该怎么办!
这个时候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) {
        }
    }
如果有” android.net.http.HttpResponseCache“这个类 就使用缓存,没有就当没这回事, 该怎么滴就怎么滴了.
注意: 如果你想使用缓存, 还有配置你的服务器让她也支持缓存哦!

开发者该选择哪个客户端使用呢?

在Eclair 和 Froyo版本中, Apache HTTP Client具有更少的BUGs,所以应该在这个版本中用Apache.
而 对于Gingerbread 及其以后的版本中, HttpURLConnection 是最好的选择. 其简洁的API和轻量级的实现用于Android系统再适合不过了. 对开发者透明的压缩和缓存实现,可以减少网络数据传输量, 提高程序响应速度 同时也节约设备电源.
新的App应该使用  HttpURLConnection;Dalvik团队的同学将会把他们的无聊时间继续投入到这个实现上来,从而增强其功能.
或许 到未来的某一天你发现 HttpURLConnection和Apache HTTP Client变得一样强大和复杂了 ! \(^o^)/~

原文E文:

Android’s HTTP Clients

Jesse Wilson

[This post is by Jesse Wilson from the Dalvik team. —Tim Bray]

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 to Froyo, 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:

privatevoid disableConnectionReuseIfNecessary(){
    // HTTP connection reuse which was buggy pre-froyo
    if(Integer.parseInt(Build.VERSION.SDK)<Build.VERSION_CODES.FROYO){
        System.setProperty("http.keepAlive","false");
    }}

In Gingerbread, 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, theclass 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.

In Ice Cream Sandwich, 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:

privatevoid enableHttpResponseCache(){
    try{
        long httpCacheSize =10*1024*1024;// 10 MiB
        File httpCacheDir =newFile(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 on Eclair and Froyo. It is the best choice for these releases.

For Gingerbread 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

分类:  Android Pro
本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/p/3738432.html如需转载请自行联系原作者

demoblog
相关文章
【计算机网络】如何让客户端构造一个HTTP请求-2
【计算机网络】如何让客户端构造一个HTTP请求-2
【计算机网络】如何让客户端构造一个HTTP请求-2
|
3月前
|
安全 搜索推荐 Android开发
Android安全性: 解释HTTPS在移动应用中的重要性。
Android安全性: 解释HTTPS在移动应用中的重要性。
21 0
|
3月前
|
存储 前端开发 JavaScript
【计算机网络】如何让客户端构造一个HTTP请求-1
【计算机网络】如何让客户端构造一个HTTP请求-1
【计算机网络】如何让客户端构造一个HTTP请求-1
|
2月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
27 0
|
3月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)(上)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
29 0
|
6天前
|
安全 Java 网络安全
Servlet 教程 之 Servlet 客户端 HTTP 请求 2
Servlet教程介绍了如何在Servlet中处理HTTP请求,包括获取Cookie、头信息、参数、Session等。方法如:`getCookies()`、`getAttributeNames()`、`getHeaderNames()`、`getParameterNames()`等。还能获取身份验证类型、字符编码、MIME类型、请求方法、远程用户信息、URL路径、安全通道状态以及请求内容长度等。此外,可通过`getSession()`创建或获取Session,并以`Map`形式获取参数。
20 8
|
3月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)(下)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
26 0
|
2天前
|
JSON 测试技术 API
Python的Api自动化测试使用HTTP客户端库发送请求
【4月更文挑战第18天】在Python中进行HTTP请求和API自动化测试有多个库可选:1) `requests`是最流行的选择,支持多种请求方法和内置JSON解析;2) `http.client`是标准库的一部分,适合需要低级别控制的用户;3) `urllib`提供URL操作,适用于复杂请求;4) `httpx`拥有类似`requests`的API,提供现代特性和异步支持。根据具体需求选择,如多数情况`requests`已足够。
8 3
|
10天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
10 0
|
27天前
解决Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com
解决Error:All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com
22 5