1.前言
- Android开发过程中,使用第三方的框架库已成家常便饭,使用第三方好处避免重复造轮子、降低成本、提升效率、降低风险等等,当遇到框架库不能满足现有业务、框架库设计缺陷或者漏洞、API使用深度不够时,如果停留只会使用层面,就会增加修改过程的难度,所以对于使用的框架库最好还是有个系统的认识;
- 本文带大家深入讲解
OkHttp
; - 文章中实例 linhaojian的Github
2.目录
3.定义
- 一款处理网络请求的开源项目,由Square公司贡献。
4.作用
- 通过**建造者模式(Builder Pattern)**方式,完成复杂的网络请求。
5.特点
- 1.同时支持HTTP1.1与支持HTTP2.0;
- 2.同时支持同步与异步请求;
- 3.同时具备HTTP与WebSocket功能;
- 4.拥有自动维护的socket连接池,减少握手次数;
- 5.拥有队列线程池,轻松写并发;
- 6.拥有Interceptors(拦截器),轻松处理请求与响应额外需求(例:请求失败重试、响应内容重定向等等);
6.OkHttp系统图
7.OkHttpClient(封装请求参数)
OkHttpClient
通过**建造者模式(Builder Pattern)**方式,完成请求参数配置。常用如下:- connectTimeout :连接超时
- readTimeout:读取超时
- writeTimeout:写入超时
- pingInterval:websocket情况下连接心跳间隔
- interceptors:自定义拦截器
- networkInterceptors:自定义网络连接成功的拦截器
OkHttpClient
除了完成请求参数的配置之外,还提供获取**WebSocket、Call(Call实现类为RealCall,下文会介绍)**相关类;
7.1 WebSocket
WebSocket
是一种在单个TCP连接上进行全双工通信的协议,支持服务器想客户端的发送请求,由OkHttpClient创建,源码如下:
/**
* Uses {@code request} to connect a new web socket.
*/
@Override public WebSocket newWebSocket(Request request, WebSocketListener listener) {
RealWebSocket webSocket = new RealWebSocket(request, listener, new Random(), pingInterval);// 1
webSocket.connect(this);
return webSocket;
}
注释1:WebSocket是一个接口,它的实现类RealWebSocket,该类完成WebSocket的连接、数据请求与接收功能。
7.2 Call初始化
//OkHttpClient 初始化Call的函数
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
// RealCall 初始化函数
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
// Safely publish the Call instance to the EventListener.
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.eventListener = client.eventListenerFactory().create(call);
return call;
}
8.RealCall同步异步
RealCall
是真正触发网络请求的类(实现Call接口,一次请求 = 一个RealCall实例),它提供了同步请求、异步请求;
8.1 同步请求
@Override public Response execute() throws IOException {
// 处理不能重复请求,因为一个RealCall对应一个请求。
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);//1
Response result = getResponseWithInterceptorChain();//2
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());//3
return chain.proceed(originalRequest);//4
}
注释1:将RealCall实例添加至Dispatcher中(下文会介绍Dispatcher)。
注释2:通过getResponseWithInterceptorChain()获取响应。
注释3:通过封装好的拦截器集合,获取第一个拦截器的任务。
注释4:触发第一个拦截器的任务,该任务就触发一下拦截器的任务,以此类推,原理(Android事件传递机制)如下图:
8.2 异步请求
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
client.dispatcher().enqueue(new AsyncCall(responseCallback));//1
}
注释1:把AsyncCall请求对象传递进Dispatcher线程池管理;
- AsyncCall 将请求业务放入到Runnable中。
final class AsyncCall extends NamedRunnable