1、okhttp的基本代码片段
OkHttpClient okHttpClient = new OkHttpClient(); // 第一行代码
Request request = new Request.Builder().url("url").build(); // 第二行代码
Call call = okHttpClient.newCall(request); // 第三行代码
call.enqueue(new Callback() { // 第四行代码
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) {
}
});
2、阅读代码流程(建议根据流程阅读源码)
3.源码分析
1)创建 OkHttpClient 对象
通过new OKHttpClient()生成一个OkhttpClient对象,在其带参数Builder的构造方法初始化一些参数(diapatcher、interceptor……)
2)发起 HTTP 请求
OkHttpClient
实现了 Call.Factory
,负责根据请求创建新的 Call
通过链式调用生成一个request对象(url、requestmethod、requestheader、requestbody)
- 检查这个 call 是否已经被执行了,每个 call 只能被执行一次,如果想要一个完全一样的 call,可以利用
call#clone
方法进行克隆。 - 利用
client.dispatcher().executed(this)
来进行实际执行,dispatcher
是刚才看到的OkHttpClient.Builder
的成员之一, - 调用
getResponseWithInterceptorChain()
函数获取 HTTP 返回结果 - 最后还要通知
dispatcher
自己已经执行完毕。
Interceptor
是最核心的一个东西,不要误以为它只负责拦截请求进行一些额外的处理(例如 cookie),实际上它把实际的网络请求、缓存、透明压缩等功能都统一了起来,每一个功能都只是一个 Interceptor
,它们再连接成一个 Interceptor.Chain
,环环相扣,最终圆满完成一次网络请求。
3)建立连接:ConnectInterceptor
4)发送和接收数据:CallServerInterceptor
- 向服务器发送 request header;
- 如果有 request body,就向服务器发送;
- 读取 response header,先构造一个
Response
对象; - 如果有 response body,就在 3 的基础上加上 body 构造一个新的
Response
对象;
核心工作都由 HttpCodec
对象完成,而 HttpCodec
实际上利用的是 Okio,而 Okio 实际上还是用的 Socket
5)返回数据的获取
- 每个 body 只能被消费一次,多次消费会抛出异常;
- body 必须被关闭,否则会发生资源泄漏
4.整体思路流程图
OkHttpClient
实现Call.Factory
,负责为Request
创建Call
;RealCall
为具体的Call
实现,其enqueue()
异步接口通过Dispatcher
利用ExecutorService
实现,而最终进行网络请求时和同步execute()
接口一致,都是通过getResponseWithInterceptorChain()
函数实现;getResponseWithInterceptorChain()
中利用Interceptor
链条,分层实现缓存、透明压缩、网络 IO 等功能;
5.OKhttpClient机制:
1)多路复用机制
OkHttp 请求之前会先从 ConnectionPool 中获取 Connection 对象,如果能获取到,则不会新建;如果获取失败,就调用 createNextConnection( ) 方法创建对象。
2)重连机制
Call 发送请求时,判断是否能 getRespose,如果不能,执行 recover,死循环获取直到重连
6.OkhttpClient设计模式
1)单例模式
内部维护了一个单例线程池。
2)Builder 模式
生成 OkHttpClient 和 Request 对象都使用 Builder 模式。
3)Interceptor 责任链模式
拦截器(Interceptor)内部使用。