一个Http请求做的事情
当我们不使用框架,而是直接使用android系统的HttpURLConnection来做http请求时候,我们一般分3步。
- 根据我们的请求目标的url地址字符串,通过URL类解析为URL对象
- 调用url.openConnection,生成一个HttpURLConnection对象
- 对生成的HttpURLConnection对象操作,写入请求的数据,接收服务端返回的数据
至此,一个简单的http或https请求就完事了。由于framework层已经给我们封装好了http相关的网络请求,所以使用起来也不是很费事,那么其底层原理是什么呢?
当我们遇到一个通信过程中的问题时候,如果不清楚其底层原理,那么根本不知道从哪里开始分析这个问题。接下来就一步步看下底层具体做了哪些事情。
- 原理图
URL对象
URL对象的存在主要是为了解析我们的url字符串的。对于一个请求,往哪里去,怎么过去,关键信息都体现到了url字符串上。最直观的就是可以直接将该字符串贴到浏览器上进行访问。
对于这样一个字符串,如何判断其格式即内容是否符合规范呢,这里就用到了URL。
通过将我们的url字符串传给URL,由URL对象统一解析,生成符合底层http请求标注的URL对象。
实例化URL对象方式很多,图示以最基本的一种为例说明,主要分几步:
-
实例化URL时候,会传入 协议(http/https),域名地址(xxxx.com),端口(9800)以及最后的目标文件(其实就是服务端暴露的接口,例如:/api/test?name=xx)
-
会先判断协议,域名和端口是否正确,正确的话,则拼接格式为 xxxx.com:9800 ,保存到URL中以做备用
-
解析目标文件为一个Parts对象,从该对象拿取URL中剩余部分的字符串,记为file。如果没有请求参数,file就是/api/test,如果有,例如上述1中的例子,file就会是/api/test?name=xx
-
根据协议(http/https)从缓存拿取(如第一次没有则新生成)对应的URLStreamHandler实例对象,HttpHandler或HttpsHandler。
-
至此实例化URL成功,返回URL
什么是URLStreamHandler
URLStreamHandler 主要定义了java 网络流相关的协议的规范,比如Http,https,ftp等都实现该抽象接口,定义各自的处理逻辑。
HttpHandler和HttpsHandler都继承于URLStreamHandler,HttpsHandler继承于HttpHandler。
url.openConnection
当我们实例化成功一个URL对象后,会紧接着调用url.openConnection方法,获取到HttpURLConnection对象。
做的事情有:
-
根据URL实例化时候选择的URLStreamHandler对象,调用其openConnection方法
-
在 HttpHandler/HttpsHandler 中,通过调用OKHttp方法,生成okUrlFactory对象
-
调用 okUrlFactory对象的open方法,生成HttpUrlConnection对象实例返回。
-
对于 HttpHandler,内部做的事情 :
-
通过对OKHttpClient进行参数设置
-
生成 okUrlFactory对象
-
分配网络连接池
-
-
对于 HttpsHandler,内部做的事情
-
调用 HttpHandler生成okUrlFactory的方法生成一个okUrlFactory对象
-
给对象设置http版本1.1
-
设置http使用tls协议
-
设置tls协议factory
-
分配网路连接池
-
可以看到,接下来就需要到OKHttp里去看HttpURLConnection具体做了什么了,我们下章分析一下OKHttp里的HttpURLConnection。