带你学开源项目:OkHttp–自己动手实现OkHttp

584 查看

一、开源项目 OkHttp

在Android、Java开发领域中,相信大家都听过或者在使用Square家大名鼎鼎的网络请求库: OkHttp https://github.com/square/okhttp ,当前多数著名的开源项目如 FrescoGlidePicassoRetrofit 都在使用OkHttp,这足以说明其质量,而且该项目仍处在不断维护中

二、问题

在分析okhttp源码之前,我想先提出一个问题,如果我们自己来设计一个网络请求库,这个库应该长什么样子?大致是什么结构呢?

下面我和大家一起来构建一个网络请求库,并在其中融入okhttp中核心的设计思想,希望借此让读者感受并学习到okhttp中的精华之处,而非仅限于了解其实现。

笔者相信,如果你能耐心阅读完本篇,不仅能对http协议有进一步理解,更能够学习到世界级项目的思维精华,提高自身思维方式。

三、思考

首先,我们假设要构建的的网络请求库叫做WingjayHttpClient,那么,作为一个网络请求库,它最基本功能是什么呢?

在我看来应该是:接收用户的请求 -> 发出请求 -> 接收响应结果并返回给用户。

那么从使用者角度而言,需要做的事是:

  1. 创建一个Request:在里面设置好目标URL;请求method如GET/POST等;一些header如Host、User-Agent等;如果你在POST上传一个表单,那么还需要body。
  2. 将创建好的Request传递给WingjayHttpClient
  3. WingjayHttpClient去执行Request,并把返回结果封装成一个Response给用户。而一个Response里应该包括statusCode如200,一些header如content-type等,可能还有body

到此即为一次完整请求的雏形。那么下面我们来具体实现这三步。

四、雏形实现

下面我们先来实现一个httpClient的雏形,只具备最基本的功能。

1. 创建Request

首先,我们要建立一个Request类,利用Request类用户可以把自己需要的参数传入进去,基本形式如下:

2. 将Request对象传递给WingjayHttpClient

我们可以设计WingjayHttpClient如下:

3. 执行Request,并把返回结果封装成一个Response返回

五、功能扩展

利用上面的雏形,可以得到其使用方法如下:

然而,上面的雏形是远远不能胜任常规的应用需求的,因此,下面再来对它添加一些常用的功能模块。

1. 重新把简陋的user Request组装成一个规范的http request

一般的request中,往往用户只会指定一个URL和method,这个简单的user request是不足以成为一个http request,我们还需要为它添加一些header,如Content-Length, Transfer-Encoding, User-Agent, Host, Connection, 和 Content-Type,如果这个request使用了cookie,那我们还要将cookie添加到这个request中。

我们可以扩展上面的sendRequest(request)方法: