一,概述
在上篇blog中可知:在RealCall的getResponseWithInterceptorChain方法中創建了許多不同類型的Interceptor對象。然後在RealInterceptorChain對象的proceed方法中有調用了Interceptor對象的intercept方法,最終返回Response對象。
Interceptor稱爲攔截器,這是OKHttp中的一個機制,它的作用是:可以對請求進行轉換,重試,重寫等操作。
Interceptor是一個接口,它的實現類有:
1. ConnectInterceptor:連接攔截器。
2. CallServerInterceptor:請求服務器攔截器
3. CacheInterceptor:緩存攔截器
4. BridgeInterceptor:橋樑攔截器。
Interceptor是一個接口,可以根據需要自定義攔截器。
下面看幾個重要的攔截器。
二ConnectInterceptor類分析
這個類的源碼不多,重要的是intercept方法,intercept方法的源碼是:
public Response intercept(Chain chain) throws IOException {
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Request request = realChain.request();
StreamAllocation streamAllocation = realChain.streamAllocation();
boolean doExtensiveHealthChecks = !request.method().equals("GET");
HttpStream httpStream = streamAllocation.newStream(client, doExtensiveHealthChecks);
RealConnection connection = streamAllocation.connection();
return realChain.proceed(request, streamAllocation, httpStream, connection);
}
分析:
- 這個方法中創建了兩個重要的對象,HttpStream 和RealConnection 。這兩個對象是請求協議和連接的核心類,後面做講解。
- 這裏又調用了realChain的proceed方法。realChain就是RealInterceptorChain對象,此時index肯定不等於0。該方法的意思是:該攔截器不做實際請求,而是處理後調用下一個攔截器,讓下一個攔截器進行處理。
三CallServerInterceptor類分析
這個類是網絡請求的本質。它的intercept方法源碼如下:
public Response intercept(Chain chain) throws IOException {
HttpStream httpStream = ((RealInterceptorChain) chain).httpStream();
StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
Request request = chain.request();
long sentRequestMillis = System.currentTimeMillis();
httpStream.writeRequestHeaders(request);//寫請求頭
if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
Sink requestBodyOut = httpStream.createRequestBody(request, request.body().contentLength());
BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
request.body().writeTo(bufferedRequestBody);//寫請求體
bufferedRequestBody.close();
}
httpStream.finishRequest();
Response response = httpStream.readResponseHeaders()
.request(request)
.handshake(streamAllocation.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();//得到response對象
if (!forWebSocket || response.code() != 101) {
response = response.newBuilder()
.body(httpStream.openResponseBody(response))
.build();//添加ResponseBody對象
}
return response;//返回response對象。
}
這個類是網絡請求的核心代碼,寫入了請求體,也得到了response對象。
寫入請求體使用的是RequestBody的writeTo方法,調用RequestBody的writeTo方法時需要傳遞一個BufferedSink 對象,這個對象是通過httpStream類的createRequestBody方法得到的。這裏我們先記住,在下一篇blog中再分析httpStream類。
四,總結
1,在ConnectInterceptor類中創建了HttpStream對象 和RealConnection 對象。
2,在CallServerInterceptor中請求網絡,創建response對象,並返回response對象。