对okhttp的源码进行了阅读,主要是学习大神的写作思路。
官网上面的okhttp的例子,我们通过例子下手,来看源码。
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
一、 没别的,首页就是OkHttpClient这个类,这个类里面东西很多,作者用了建造者模式(Builder Pattern)。当然在例子里面看不出来,但是,作者在类的注释里面给了范例。
// The singleton HTTP client.
public final OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor())
.cache(new Cache(cacheDir, cacheSize))
.build();
二、Request同样也是使用了建造者模式,这里面主要就请求的url,参数,请求头,请求体的设置。
final HttpUrl url;
final String method;
final Headers headers;
final RequestBody body;
final Object tag;
三、 Response response = client.newCall(request).execute();
对于网络请求,出现在Call这个接口里面,而RealCall是具体的实现类,所以我们重点看RealCall这个类。
官方给的实例里面,调用了execute的方法,这个是同步请求,还有异步的请求enqueue方法。
- 同步的请求,直接返回了Response
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
}
2.异步请求需要AsyncCall回调
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
在AsyncCall里面调用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 {
responseCallback.onFailure(RealCall.this, e);
}
} finally {
client.dispatcher().finished(this);
}
}
}
- 不管是同步还是异步,都会出现getResponseWithInterceptorChain()这个方法。这个okhttp的核心业务。
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
//重定向拦截器
interceptors.add(retryAndFollowUpInterceptor);
//对request进行重新封装以及对返回的response进行处理到用户可以使用
interceptors.add(new BridgeInterceptor(client.cookieJar()));
//缓存拦截器
interceptors.add(new CacheInterceptor(client.internalCache()));
//socket建立连接
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);
return chain.proceed(originalRequest);
}
这个是一个拦截器列表, 每个拦截器有自己的作用,调用chain.proceed(originalRequest)方法,这里面使用了递归
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
在每个拦截器里面的intercept方法里面调用chain.proceed(originalRequest)。