Android总结 - 网络请求总结

HttpURLConnection

建立连接

Android在6.0之后只支持HttpURLConnection来做Http的请求。从crash时候的log里面看出HttpURLConnection底层已经开始使用OkHttp了。总结一下常用的使用方法。
使用流程如下:
1. 打开连接。通过URL.openConnection()来获取一个HttpURLConnection
2. 准备请求。一个请求的最主要的部分是URI。请求头部可以包含好多metadata比如:证书、优先内容类型和session cookies。
3. 可选的上传请求body。 如果包含一个请求body 实例,必须调用setDoOutput(true)来配置。 通过getOutputStream()获取输出流来发送数据。
4. 读取response响应 Response头部典型的包含metadata比如响应实体的content type和length,modified dates 和session cookies 。响应内容可以通过getInputStream()获取输入流来读取。如果response没有body,getInputStream()会返回一个空的流。
5. 关闭连接。response body被读完之后就应该disconnect()关闭HttpURLConnection。关闭连接可以释放相关的资源以便于他们可以被关闭或重新使用。

普通的get请求列子:

  URL url = new URL("http://www.android.com/");
   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in); // 自己实现读取数据并处理
    finally {
     urlConnection.disconnect();
   }

使用HTTPS做安全通信

Calling openConnection() on a URL with the “https” scheme will return an HttpsURLConnection, which allows for overriding the default HostnameVerifier and SSLSocketFactory. An application-supplied SSLSocketFactory created from an SSLContext can provide a custom X509TrustManager for verifying certificate chains and a custom X509KeyManager for supplying client certificates. See HttpsURLConnection for more details.

响应操作

HttpURLConnection 会跟踪5次HTTP重定向,它会跟踪从原始服务器到另一个。但是不支持重定向从HTTPS to HTTP or vice versa。
如果HTTP response指示有一个错误出现, getInputStream()会抛出 IOException异常。使用getErrorStream()来读取错误的response。响应头部headers还是可以通过正常的方法getHeaderFields()来读取。

发送内容

如果要上传数据到服务器,需要使用setDoOutput(true)来配置连接。
为了有最好的性能,当request body的长度提前已知的情况下,需要调用setFixedLengthStreamingMode(int);当request body的长度未知的情况下,要么就调用setChunkedStreamingMode(int)。否则HttpURLConnection会强制在内存中缓存整个request body在被传递之前,这样会浪费堆栈和增加延迟。

Post例子:

   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   try {
     urlConnection.setDoOutput(true);
     urlConnection.setChunkedStreamingMode(0); // 参数0代表使用默认的chunk长度。

     OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
     writeStream(out);

     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in);
    finally {
     urlConnection.disconnect();
   }

执行效率

HttpURLConnection返回的输入和输出流是没有缓存的。使用者必须使用 BufferedInputStream or BufferedOutputStream来包装原始的流。只有当批量读写的时候才可以忽略使用缓存。

当传递大量数据到服务器或者从服务器获取大量数据的时候,使用streams来限制内存一次性可以加载多少数据。除非你是需要把entire body 一次性的加载到内存中,要不然就把它作为流来处理(而不是保存整个body为字节数组或者字符串)

为了降低延迟,HttpURLConnection会为多个请求/响应对而复用同一个底层Socket。因此,HTTP链接打开的时间会比必要的时间更长一点。调用 disconnect()可以把socket返回到已连接的sockets线程池中。在发送任何HTTP请求之前,通过设置“http.keepAlive”property为false,可以禁止这种行为。“http.maxConnections property ”可以用来控制每个服务器的最大空闲连接数。

默认情况下,HttpURLConnection 实现请求服务器使用gzip压缩发送并且会自动解压缩从getInputStream()获取的数据。这种情况下 Content-Encoding 和 Content-Length 的reponse headers会被清空(此时,getContentLength() 会返回 -1,如果想要使用getContentLength() 需要禁用gzip压缩)。Gzip压缩可以通过设置请求头部里面的“acceptable encodings”属性来禁止:

   urlConnection.setRequestProperty("Accept-Encoding", "identity");

设置请求头部“Accept-Encoding”属性可以明确的禁用自动解压并保持response headers的完整性;如果需要的话,调用者可以根据response header中的“Content-Encoding”来进行解压。

getContentLength() 会返回被传输内容的字节数量,但是不能用来预测会有多少字节会从getInputStream()中读出来。反而,应用通过读取stream直到耗尽,比如read() 返回-1。

控制网络登录

有些Wifi网络需要通过一个登陆界面登陆之后才能访问网络。这种类似的登陆界面通常都是使用了HTTP的重定向。可以通过使用getURL() 来测试我们的connection 是否被意外的重定向了。在response headers被接收到之前这种检查不可用,而response headers可以通过调用 getHeaderFields()或者getInputStream()来触发得到。
例子,检测response是否被意外重定向到别的host:

   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     if (!url.getHost().equals(urlConnection.getURL().getHost())) {
       // we were redirected! Kick the user out to the browser to sign on?

     ...
   } finally {
     urlConnection.disconnect();
   }
 }

HTTP Authentication

Sessions with Cookies

为了在客户端和服务端建立和维持一个潜在的长session,HttpURLConnection包含一个可扩展的cookie管理器。使用 CookieHandler and CookieManager来启动VM-wide cookie management:

   CookieManager cookieManager = new CookieManager();
   CookieHandler.setDefault(cookieManager);

默认的,CookieManager只接受原始服务器过来的cookies,除此之外还有两种其他的两种策略:ACCEPT_ALL 和ACCEPT_NONE,通过实现CookiePolicy 去定义一个自定义的policy。

这个默认的CookieManager 在内存中保留着所有可接受的cookies。这个cookies会被遗忘当VM退出的时候。可以通过继承CookieStore来自定义cookie store。

除了被HTTP responses设置过的cookies,其他的cookies需要自己手动设置。为了包含在HTTP的请求头部中,cookies必须设置domain 和 path 属性。

默认的,HttpCookie 实例只能与支持“RFC 2965 ”cookies的服务器一起工作。好多服务器只支持就的规则“RFC 2109”。为了与大部分服务器兼容,设置cookie version为0。

举例, 接收“ www.twitter.com” in French:

 HttpCookie cookie = new HttpCookie("lang", "fr");
 cookie.setDomain("twitter.com");
 cookie.setPath("/");
 cookie.setVersion(0);
 cookieManager.getCookieStore().add(newURI("http://twitter.com/"), cookie);

HTTP Methods

HttpURLConnection默认使用GET方法,通过调用“setDoOutput(true)” 来使用POST方法。其他的HTTP方法(OPTIONS, HEAD, PUT, DELETE and TRACE)可以用调用”setRequestMethod(String)“来使用。

Proxies

HttpURLConnection默认是直接连接。当然也可以通过HTTP或者SOCKS代理来建立连接。通过调用URL.openConnection(Proxy) 来建立代理连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值