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

一、开源项目 OkHttp

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

PS :有兴趣的加入Android工程师交流QQ群:752016839 主要针对Android开发人员提升自己,突破瓶颈,相信你来学习,会有提升和收获。

二、问题

在分析 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 类用户可以把自己需要的参数传入进去,基本形式如下:

 

1

2

3

4

5

6

7

8

9

10

11

 

class Request {

String url;

String method;

Headers headers;

Body requestBody;

public Request(String url, String method, @Nullable Headers headers, @Nullable Body body) {

this.url = url;

...

}

}

 

2. 将 Request 对象传递给 WingjayHttpClient

我们可以设计 WingjayHttpClient 如下:

 

1

2

3

4

5

 

class WingjayHttpClient {

public Response sendRequest(Request request) {

return executeRequest(request);

}

}

 

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

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

 

class WingjayHttpClient {

...

private Response executeRequest(Request request) {

// 使用 socket 来进行访问

Socket socket = new Socket(request.getUrl(), 80);

ResponseData data = socket.connect().getResponseData();

return new Response(data);

}

...

}

class Response {

int statusCode;

Headers headers;

Body responseBody

...

}

五、功能扩展

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

 

1

2

3

4

 

Request request = new Request("http://wingjay.com");

WingjayHttpClient client = new WingjayHttpClient();

Response response = client.sendRequest(request);

handle(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) 方法:

 

1

2

3<

你可能感兴趣的:(Android)