android 没有url对象,Android中HttpURLConnection对象是怎么生成的

1 try{2 URL mUrl = new URL("https://www.jianshu.com/");3 HttpURLConnection http =(HttpURLConnection) mUrl.openConnection();4 http.setRequestMethod("GET");5 http.setConnectTimeout(1024);6 http.connect();7 int ret =http.getResponseCode();8 Log.d("tag", "JianShu response:" +ret);9 } catch(Exception e) {10 e.printStackTrace();11 }

上面的代码块是在Android中使用HttpURLConnection方式访问网站的最简单的代码演示。本篇文章要讲的是上述代码的前两行的流程。即如果你有一个网址字符串,Android是如何把它封装成HttpURLConnection对象的。

其实关于HttpURLConnection访问互联网完全是属于Java层的知识,可以说与Android没有任何关系。但由于我本人是在 Android4.4 源代码环境下进行分析的,并且在Android源代码下我可以很方便地去给这些源码添加打印来跟踪其流程,因此这篇文章就叫在Android下的HttpURLConnection对象由来跟踪。

首先来看看URL对象的实例化过程。打开源码:

./libcore/luni/src/main/java/java/net/URL.java

5015e1e2e013381107b46d4adb716f13.png

图1 URL对象的实例化

URL支持以旧的URL对象来实例化新URL对象,不过我想大多数情况下都是只传一个网址参数来实例化的。

c2a7c7764f29bb768ce9e7ad111ad2a9.png

图2 URL对象的实例化

对于只传一个网址字符串参数进来实例化的情况,上图带三个参数的URL构造方法大多数代码都不需要去理它。这里值得关心的是上图代码第180行调用的setupStreamHandler()方法。setupStreamHandler()方法里就是实例化一个URLStreamHandler对象而已。setupStreamHandler()方法前半部分也不怎么需要去关心它。只看它后半部分的实现。

0e6cc3e3703f59613ec828ce08e09d1b.png

图3 setupStreamHandler()后半部分的实现

这块代码就很通俗易懂了,就是根据你前面传进来的网址的前缀来决定实例化哪个URLStreamHandler的子类而已。本例中我们传递的是Https类型的网址,故而URL类对象中的成员变量streamHandler在实例化过后所指向的类对象是 HttpsHandler 类对象。

./external/okhttp/android/main/java/com/squareup/okhttp/HttpsHandler.java

接着上图2,streamHandler变量完成赋值后就接下去执行第188行的URL解析了,这部分代码没什么好讲的。只要你传递的网址参数是合法的,就不用理会它,在我们的正常项目中,也不会有人故意传个不正确的网址下去。

至此,URL对象的实例化就已经完成了。Android已经将我们的网址字符串转化成了URL对象了。

--------------------------------------------------------------------------------------------------

下面我们再看看

mUrl.openConnection();

这个代码在执行的时候其内部都发生了些什么。

首先还是找到URL中关于openConnection()方法的实现。

9260319ed01ab963dcbe4ae219795b89.png

图4 mUrl.openConnection()

顺着前面分析到的streamHandler的引用对象一路跟上去。发现它会调到

./external/okhttp/android/main/java/com/squareup/okhttp/HttpHandler.java

30f0a4cf1bf82ed73b988a8d413cbb95.png

图5 httphandler.openConnection()

newOkHttpClient()方法的实现如下图所示。

ed35e898e5e6b397cd2882f965384f62.png

图6 newOkHttpClient()

这里,实例化出一个OkHttpClient类对象后调用它的open()方法,将open()方法执行过后得到的对象作为URLConnection对象返回给APK调用者。

./external/okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java

ebf826820c5bbc96e7e1af844a7fc659.png

图7 OkHttpClient

这块代码也够清晰明了了。就本篇例子而言,会去实例化HttpsURLConnectionImpl类对象。

./external/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpsURLConnectionImpl.java

HttpsURLConnectionImpl.java继承自HttpsURLConnection.java

./libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java

而HttpsURLConnection.java又继承自HttpURLConnection.java

./libcore/luni/src/main/java/java/net/HttpURLConnection.java

至此,我们算是弄明白了Android在拿到用户传入的网址后都干了些什么事,并最终把它封装成HttpURLConnection对象的了。

HttpURLConnection http = (HttpURLConnection) mUrl.openConnection();

换言之,文首贴出的代码中的 http 变量指向的类对象其实是上面流程分析中提到的HttpsURLConnectionImpl类的对象。而假若传入的网址是 http:// 形式的,那么它指向的就是HttpURLConnectionImpl类对象了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值