版本:com.squareup.okhttp3:okhttp:3.11.0
1、call.eventListener = client.eventListenerFactory().create(call)
建立连接(tcp、tls)
2、client.dispatcher().enqueue(new AsyncCall(responseCallback));
dispatcher(): 处理线程
enqueue(..): 成立的情况下就会去让线程管理去管理线程,让 call 在后台去执行,
如果不成立则会添加到 readyAsyncCalls 队列中,一个待用的队列,随时可能发送请求
AsyncCall:会调用父类run方法中的 execute(),实现在 RealCall 的 execute() 中。
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
eventListener.callFailed(RealCall.this, e);
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
}
3、okhttpclient配置项
final Dispatcher dispatcher;线程调度管理器
final @Nullable Proxy proxy;设置代理服务器,如果我们无法访问或访问失败我们的目标服务器,可以交给代理服务器去帮我们访问想要访问的目标服务器
final List protocols; 所支持的 http 协议版本
final List connectionSpecs;配置使用http还是https;包括SSL和TLS版本的选择配置
final List interceptors;
final List networkInterceptors;
final EventListener.Factory eventListenerFactory;
final ProxySelector proxySelector;
final CookieJar cookieJar;cookie存储器
final @Nullable Cache cache;http的cache
final @Nullable InternalCache internalCache;
final SocketFactory socketFactory;创建tcp端口
final @Nullable SSLSocketFactory sslSocketFactory;创建SSL端口
final @Nullable CertificateChainCleaner certificateChainCleaner;整理服务器传输而来的证书
final HostnameVerifier hostnameVerifier;用于https中,验证对方服务器的host
final CertificatePinner certificatePinner;做自签名
final Authenticator proxyAuthenticator;Head中添加Authorizaion,访问权限配置
final Authenticator authenticator;
final ConnectionPool connectionPool;连接池
final Dns dns;
final boolean followSslRedirects;当遇到http与https互相跳转,是否跳?
final boolean followRedirects;如果遇到需要跳转的情况下,是否去跳转,比如返回3xx,默认是true
final boolean retryOnConnectionFailure;请求失败,是否重新连接
final int connectTimeout;tcp链接时间
final int readTimeout;下载等待响应时间
final int writeTimeout;写入响应时间
final int pingInterval;针对wbsocket的,多久ping一次,客户端发送ping,服务端发送pong
//自签名
public void mySingn() {
String hostname = "hencoder.com";
CertificatePinner certificatePinner = new CertificatePinner.Builder()
// .add(hostname, "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
.add(hostname, "sha256/rZ/xwvaoWYYzhWGtTUCUNO07mHKM82JCfdvWZm1Z7nU=")
.add(hostname, "sha256/GI75anSEdkuHj05mreE0Sd9jE6dVqUIzzXRHHlZBVbI=")
.add(hostname, "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=")
.build();
OkHttpClient client = new OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build();
Request request = new Request.Builder()
.url("https://" + hostname)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("qqq","onFailure...");
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i("qqq","onSuccess...");
}
});
}
4、分析execute中的getResponseWithInterceptorChain
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List 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());
return chain.proceed(originalRequest);
}
作用:将准备好的请求去做网络请求,然后得到响应(response)
责任链模式
chain.proceed 的流程如上图。
先做请求的前置工作,然后调用proceed()方法,如果proceed()方法返回成功,则会接着去做响应后置工作;在proceed()方法执行过程中,又会去调用下一个拦截器的请求前置工作、proceed()、响应后置工作。。。
client.interceptors():做拦截工作,可以在请求前做一些处理,或者在请求之后做一些处理
retryAndFollowUpInterceptor:用于网络的重试工作
BridgeInterceptor:封装request和response的过滤器,各种http参数的设置,Content-Type、User-Agent等等
CacheInterceptor:如果已有的cache信息,还在保存期内,那么就直接使用cache中的数据,则不会再去做接下来的网络请求
ConnectInterceptor:在该拦截器中与TCP、HTTPS的TLS来做交互,即建立一个TCP连接或者在TCP的连接上再叠加一个TLS连接。(该拦截器没有后置工作)
client.networkInterceptors():配置 OkHttpClient 时设置的 networkInterceptors,一般很少用,主要用 client.interceptors()
CallServerInterceptor:负责向服务器发送请求数据、从服务器读取响应数据(实际网络请求)
优点:
可以看到,这里首先new了一个Interceptor的ArrayList,然后分别加入了各种各样的Interceptor,所以当我们默认创建okHttpClient时,okHttp默认会给我们实现这些过滤器,每个过滤器执行不同的任务,这个思想太屌了有木有,每个过滤器负责自己的任务,各个过滤器间相互不耦合,高内聚,低耦合,对拓展放开巴拉巴拉等一系列设计思想有木有,这里可以对比一下Volley源码中的思想,Volley的处理是将缓存,网络请求等一系列操作揉在一起写,导致用户对于Volley的修改只能通过修改源码方式,而修改就必须要充分阅读理解volley整个的流程,可能一部分的修改会影响全局的流程,而这里,将不同的职责的过滤器分别单独出来,用户只需要对关注的某一个功能项进行理解,并可以进行扩充修改,一对比,okHttp在这方面的优势立马体现出来了。这里大概先描述一下几个过滤器的功能
面试题
1、okhttp 的原理。先重定向再查缓存?请求池?