HttpURLConnection源码解析

参考:

HttpURLConnection 源码分析

Android 网络(三) HttpURLConnection OkHttp

OKHttp源码解析

概述

在Android应用中大都会使用Http协议来访问网络, Android主要提供了两种方式(HttpURLConnection、HttpClient)来进行Http操作,具体选择哪种可以参考Android访问网络,使用HttpURLConnection还是HttpClient?。现在的应用最低版本都不会低于Android2.3,应该使用HttpURLConnection进行网络请求,并且在Android6.0版本中HttpClient已经被移除。

在TCP/IP的五层协议模型中,Socket是对传输层协议的封装,Socket本身并不是协议,而是一个调用接口(API),目前传输层协议有TCP、UDP协议两种,Socket可以指定使用的传输层协议,当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。HttpURLConnection建立的连接是TCP连接,TCP连接的建立需要经过三次握手过程。

再多说一句,4.4版本之后HttpURLConnection底层是基于OkHttp实现的,下面的源码解析中也可以看出来。

主要的实现代码如下:

URL url = new URL("https://certs.cac.washington.edu/CAtest/");
HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
//connect()方法不必显式调用,当调用conn.getInputStream()方法时内部也会自动调用connect方法
urlConnection.connect();
//调用getInputStream方法后,服务端才会收到完整的请求,并阻塞式地接收服务端返回的数据
InputStream in = urlConnection.getInputStream();

源码分析

这里引用了一张其他人的时序图,可以通过这个先看下整体的流程

1. url.openConnection()方法,其中handler是URLStreamHandler,可以发现这个是个抽象类,具体实现并不在这里面,需要再找handler是哪里进行赋值的。

2. handler是通过getURLStreamHandler方法中赋值的,可以看到,底层是okhttp进行实现的,从Android 4.4开始使用okhttp处理HTTP协议。

3. 实际上就是调用com.android.okhttp.HttpHandler.openConnection()方法

4. 调用的是OkUrlFactory的open方法,根据请求方式返回HttpURLConnectionImpl或者HttpsURLConnectionImpl

5. 查看HttpURLConnectionImpl的connect()方法

再看下execute方法内部

sendRequest方法

connect方法

StreamAllocation的newStream方法

findHealthyConnection寻找一个健康的连接,

StreamAllocation的findConnection方法,如果没有找到,就创建一个新的连接,首先将新创建的连接实例放到连接池,然后通过新创建的连接实例与服务端建立Socket连接,最后将新创建的连接返回。

newConnection.connect通过新创建的连接与服务端建立Socket连接

RealConnection的connectSocket方法,通过Socket建立TCP连接

最后就是使用Socket的connect方法进行连接了。

6. HttpURLConnectionImpl的getInputStream方法

看一下getResponse()这个方法,这里也是调用了execute方法,所以connect()方法不必显示调用,getInputStream()方法中也会进行调用

httpEngine.readResponse()读取网络响应

上面大致分析了一下HttpURLConnection请求的流程,简单概况:Soket实现TCP连接,OkHttp实现具体的网络请求,HttpURLConnection则提供了一组轻量级的API方便我们使用和拓展。

缓存实现

缓存对移动端来说还是十分重要的,可以先看下HTTP的缓存策略:

通过上图可以看出,缓存过程一般发生在两个地方,发送请求和处理响应中,然后从上面对HttpURLConnection请求过程的分析我们知道这两个过程对应HttpEngine的sendRequest()readResponse()方法,接下来我们再详细分析下这两个方法。

 

  • sendRequest中判断是否需要重新从服务端获取
  • readResponse中判断响应是从缓存中读取还是调用readNetworkResponse()方法获取

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值