回顾
在OkHttp3学习(二):发送一个请求中 我们看到了当我们发送一个请求时,通过client.newCall(request)
来创建一个RealCall
实例,当我们调用RealCall
的execute()
的时候会调用client
对象的dispatcher
的execute()
方法来执行这个RealCall
。当我们调用了RealCall
的enqueue()
方法之后会在内部调用Client
对象的dispatcher
的execute()
方法时创建一个AsyncCall
对象,并执行这个AsyncCall
的execute
方法。不管是client.newCall(request).execute()
还是client.newCall(request).enqueue(new Callback(){})
我们会发现对应的Call的execute()
都会得到执行。
execute()
既然RealCall
和AsyncCall
的execute()
都会得到执行,那他们又有什么共同之处呢,相应又是怎么获得的呢?
这是RealCall
的execute()
去除了部分代码之后的
@Override public Response execute() throws IOException {
captureCallStackTrace();
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
return result;
} finally {
client.dispatcher().finished(this);
}
}
这是AsyncCall
去掉部分代码后的execute()
@Override protected void execute() {
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException e) {
//...
} finally {
client.dispatcher().finished(this);
}
}
在这两个代码中我们看到。请求的响应(Responce
)都是通过getResponseWithInterceptorChain()
方法获取的。其代码是这样的:
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);
return chain.proceed(originalRequest);
}
在这些代码中我们看到了一堆的Interceptor
那么这又是个什么鬼呢?
Interceptor
官方关于Interceptor
的介绍:点这里
看下这个图。看下这个例子自定义一个Inteceptor
应该不成问题了。例子在文档中有。
/** This interceptor compresses the HTTP request body. Many webservers can't handle this! */
final class GzipRequestInterceptor implements Interceptor {
@Override public Response intercept(Interceptor.Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
return chain.proceed(originalRequest);
}
Request compressedRequest = originalRequest.newBuilder()
.header("Content-Encoding", "gzip")
.method(originalRequest.method(), gzip(originalRequest.body()))
.build();
return chain.proceed(compressedRequest);
}
private RequestBody gzip(final RequestBody body) {
return new RequestBody() {
@Override public MediaType contentType() {
return body.contentType();
}
@Override public long contentLength() {
return -1; // We don't know the compressed length in advance!
}
@Override public void writeTo(BufferedSink sink) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
body.writeTo(gzipSink);
gzipSink.close();
}
};
}
}
通过下面的方法将一个自定义的Inteceptor
加入到请求中。
OkHttpClient client= new OkHttpClient
.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
return null;
}
})
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
return null;
}
}).build();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。