代码使用
Request build1 = new Request.Builder().url("").addHeader("", "").build();
OkHttpClient build = new OkHttpClient.Builder().build();
Call call = build.newCall(build1);
try {
call.execute();
} catch (IOException e) {
e.printStackTrace();
}
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
Request主要是设置基础域名,请求头,清楚参数等信息,构造方法如下,用到建造者模式
Request(Builder builder) {
this.url = builder.url;
this.method = builder.method;
this.headers = builder.headers.build();
this.body = builder.body;
this.tags = Util.immutableMap(builder.tags);
}
OkHttpClient类的主要参数
OkHttpClient(Builder builder) { 不不不
this.dispatcher = builder.dispatcher;
this.proxy = builder.proxy;
this.protocols = builder.protocols;
this.connectionSpecs = builder.connectionSpecs;
this.interceptors = Util.immutableList(builder.interceptors);
this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
this.eventListenerFactory = builder.eventListenerFactory;
this.proxySelector = builder.proxySelector;
this.cookieJar = builder.cookieJar;
this.cache = builder.cache;
this.internalCache = builder.internalCache;
this.socketFactory = builder.socketFactory;
boolean isTLS = false;
for (ConnectionSpec spec : connectionSpecs) {
isTLS = isTLS || spec.isTls();
}
if (builder.sslSocketFactory != null || !isTLS) {
this.sslSocketFactory = builder.sslSocketFactory;
this.certificateChainCleaner = builder.certificateChainCleaner;
} else {
X509TrustManager trustManager = Util.platformTrustManager();
this.sslSocketFactory = newSslSocketFactory(trustManager);
this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
}
if (sslSocketFactory != null) {
Platform.get().configureSslSocketFactory(sslSocketFactory);
}
this.hostnameVerifier = builder.hostnameVerifier;
this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
certificateChainCleaner);
this.proxyAuthenticator = builder.proxyAuthenticator;
this.authenticator = builder.authenticator;
this.connectionPool = builder.connectionPool;
this.dns = builder.dns;
this.followSslRedirects = builder.followSslRedirects;
this.followRedirects = builder.followRedirects;
this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
this.connectTimeout = builder.connectTimeout;
this.readTimeout = builder.readTimeout;
this.writeTimeout = builder.writeTimeout;
this.pingInterval = builder.pingInterval;
if (interceptors.contains(null)) {
throw new IllegalStateException("Null interceptor: " + interceptors);
}
if (networkInterceptors.contains(null)) {
throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
}
}
Call的生成:
Call call = okHttpClient.newCall(build1);
Call类是个接口类,里面主要方法是execute和enqueue 主要处理同步和异步的方法 其实现类是RealCall
public interface Call extends Cloneable {
Response execute() throws IOException;
void enqueue(Callback responseCallback);
}
newCall会实例化RealCall类
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
然后调用RealCall的enqueue方法执行异步任务
@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));
}
其中client.dispatcher()是请求处理类,负责创建线程池,执行线程,取消请求等任务,该类在OkHTTPClient的初始化
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
maxRequests是请求的最大并发数,若超过这个限制(默认是64),请求任务则会进入等待队列
runningCallsForHost(call) < maxRequestsPerHost是限制host的并发访问次数(默认是个),避免造成服务器的负载。
AsyncCall是RealCall的内部类,可以理解成任务,我们每发起一个请求会创建一个实例,它是NamedRunnable的实现类
//AsyncCall类
final class AsyncCall extends NamedRunnable {
@Override protected void execute() {
boolean signalledCallback = false;
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
responseCallback.onResponse(RealCall.this, response);
}
}
}
//NamedRunnable类
public abstract class NamedRunnable implements Runnable {
@Override public final void run() {
try {
execute();
} finally {
}
}
protected abstract void execute();
}
NamedRunnable是实现与Runnable 它是一个线程,当执行时会触发AsynCall的execute()方法,通过源码可知Response是在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()));
//连接拦截器-httpCodec在这里初始化,httpCodec分http1.0和2.0
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);
}
首先会依次实例化各个请求拦截器,处理拦截器是用到责任链模式,我们看下chain.proceed(request)方法
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
RealConnection connection) throws IOException {
//获取下个拦截器实例
RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
writeTimeout);
//获取当前拦截器
Interceptor interceptor = interceptors.get(index);
//执行当前拦截器,并把下个拦截器传入进去方便执行
Response response = interceptor.intercept(next);
return response;
}
在执行当前拦截器的时候 会创建并传递下个拦截的实例,这样调用intercept方法执行完当前拦截器时,调用proceed方法可以再次触发上面的代码,以达到一个链式的调用。