一、总结
一、网络请求流程
OkHttp分同步网络请求和异步网络请求。
第一步:通过建造者模式来创建OkHttpClient对象。会创建默认的参数。我们也可以在这里传入自己配置的构建参数,比如设置超时时间、自定义拦截器、
❌创建OkHttpClient客户端对象,OkHttpClient通过建造者模式来封装OkHttpClient初始化需要的参数,主要进行了dispatcher、connectionPool(连接池)等创建。❌
第二步:通过建造者模式创建了Request,这这里面主要封装了。创建Request对象,通过建造者模式封装请求报文信息、请求地址、请求方法和请求头,默认请求方法为get。
第三步:通过OkHttpClient和request创建realCall。
第四步:如果是同步请求,会调用realCall的execute方法。
第五步:如果是异步请求,会调用realCall的enqueue方法。此时我们要传入Callback,用于回调成功或失败。
二、同步请求
如果是同步请求,会通过dispatcher将call添加到runningSyncCalls同步请求队列中。然后调用拦截器链方法获得response。请求结束后,从同步请求队列移除这个同步请求。
三、异步请求
如果是异步请求,首先创建AsyncCall对象,里面封装了realCall。AsyncCall实现了Runnable。然后把AsyncCall添加到readyAsyncCalls缓存等待的请求队列中。然后调用promoteAndExecute方法,这个方法的作用是调整异步请求队列和缓存请求队列。遍历异步缓存队列,然后判断正在执行的异步请求队列runningAsyncCalls的size是否小于64或同host的小于5,如果满足条件将任务添加到正在执行的异步请求队列中,然后从异步缓存队列中将任务移除。然后调用executorService线程池执行AsyncCall,之后调用AsyncCall的run方法。在run方法中调用拦截器链方法获得response。任务请求结束后,从异步请求队列移除当前请求,之后继续调用promoteAndExecute方法。
四、调用executorService线程池执行AsyncCall
调用executorService线程池执行AsyncCall。Runnable实现了Runnable,所以会调用run方法。然后执行AsyncCall的execute方法。然后创建RealInterceptorChain拦截器链,将我们自定义的ApplicationInterceptor和五大拦截器重试拦截器、桥接连接器、缓存拦截器、连接拦截器和网络请求拦截器和NetwrokInterceptor添加到集合中。然后通过链式调用顺序调用拦截器的intercept方法获取response,然后将response返回给上一个拦截器。
五、Application Interceptor
Application Interceptor 是第一个执行的拦截器,Application Interceptor 适用于在请求前统一添加一些公共参数,例如在添加 APP 的版本号,用户 ID ,手机版本号,运营商类型等参数。或者对响应体的数据进行 json 转化等操作。比如DebugInterceptor,在网络请求是拦截请求,返回我们自定义的json数据,方便数据联调。他的原理是,这是拦截器链走的第一个方法,我们判断是否对请求进行拦截,如果拦截的话,终止链式调用,直接将我们从本地文件读取的json作为response返回。
六、RetryAndFollowUpInterceptor
RetryAndFollowUpInterceptor重试和重定向拦截器,开启一个while (true) 循环,在死循环中会调用接下来的拦截器方法获取网络请求,如果请求失败,会进行重试请求。如果重试次数超过20次,会终止循环,抛出异常。
七、BridgeInterceptor
BridgeInterceptor桥接适配拦截器,在这里将我们的request转化为可以进行网络请求的request,添加头部信息比如Content-Type、Content-Length、Transfer-Encoding、Host、Connection=”Keep-Alive”保持长连接,Accept-Encoding、Cookie、User-Agent。然后调用拦截器链方法获取网络数据,然后对response进行解析,比如变成我们可以使用的response。比如gzip解压缩,responseCode是否为200等。
八、CacheInterceptor
CacheInterceptor缓存拦截器,根据request从磁盘缓存DiskLruCache中获取缓存,如果网络请求和缓存为空会抛出504异常。如果网络请求为空,缓存不为空会直接返回缓存。
否则进行网络请求,调用拦截器链方法获取response,如果缓存不为空,会对responseCode进行判断,如果等于304直接返回缓存,然后更新缓存数据。如果缓存为空,会保存缓存。也会将缓存中无效的request对应的缓存删除。
九、ConnectInterceptor
ConnectInterceptor网络链接拦截器,在这里会创建exchange,exchange会携带request和response。在这里我们会获取网络链接,首先判断是否有合适的链接,如果没有我们连接池取,复用已有的链接。如果还是没有,我们会自己创建一个链接RealConnection。然后调用RealConnection的connect方法,进行TCP 和 TLS 握手。
十、networkInterceptor
接下来,就是我们自定义的networkInterceptors,在这里可以获取到最终发送请求的 request ,也可以获取到真正发生网络请求回来的 response 响应
十一、CallServerInterceptor
CallServerInterceptor:对我们的请求头和请求体进行写入,然后调用Okio进行真正的IO流操作。之后读取服务器返回的response。然后返回上一级拦截器。
十二、调用dispatcher的finish方法
网络请求成功后,再次调用promoteAndExecute方法,从异步请求队列中将当前请求移除,对异步缓存队列和异步请求队列进行调整,判断是否进行下个任务。
二、Interceptor和NetwrokInterceptor区别
- Application Interceptor 因为是第一个被执行的拦截器,因此它有权决定了是否要调用其他拦截,也就是 Chain.proceed() 方法是否要被执行。适用于在请求前统一添加一些公共参数,例如在添加 APP 的版本号,用户 ID ,手机版本号,运营商类型等参数。或者对响应体的数据进行 json 转化等操作。比如DebugInterceptor、添加请求头信息、对response统一进行处理。
- NetworkInterceptor:因为 NetworkInterceptor 是排在第 6 个拦截器中,可以获取到最终发送请求的 request ,也可以获取到真正发生网络请求回来的 response 响应。对于从缓存获取的 response 则不会去触发 NetworkInterceptor 。因为响应直接从 CacheInterceptor 返回了。可以使用日志拦截器。
二、源码解析,以异步请求为主。
1、请求代码
作用:
(1)创建OkHttpClient客户端对象
(1)通过建造者模式创建了Request
(1)执行realCall的enqueue方法
//1.新建OKHttpClient客户端
val okHttpClient = OkHttpClient.Builder().build()
//2、新建一个Request对象
val request = Request.Builder().url("").build()
val realCall = okHttpClient.newCall(request)
realCall.enqueue(object : Callback{
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
}
})
2、调用RealCall的enqueue方法
作用:
(1)传入了Callback接口对象,用于接口回调。
(2)创建AsyncCall对象,里面封装了realCall。AsyncCall实现了Runnable。线程池会执行AsyncCall,调用AsyncCall的run方法。
(3)调用dispatcher的enqueue方法,
@Override public void enqueue(Callback responseCallback) {
//1、加了锁
synchronized (this) {
//2、只能执行一次,如果再次执行会抛出异常
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
transmitter.callStart();
//3、重点在这里
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
3、调用dispatcher的enqueue方法
1)作用:
(1)把AsyncCall添加到readyAsyncCalls异步缓存请求队列中,
(2)调用promoteAndExecute方法。
void enqueue(AsyncCall call) {
synchronized (this) {
//1、把call添加到异步缓存请求队列中
readyAsyncCalls.add(call);
//省略部分代码
、、、、
//2、调用此方法
promoteAndExecute();
}
2)Dispatcher的作用
Dispatcher管理同步和异步请求,维护了三个任务队列,并维护一个线程池用于执行异步请求,让网络请求变得更高效。
readyAsyncCalls:缓存等待的请求队列
runningAsyncCalls:正在执行的异步请求队列。
runningSyncCalls:正在执行的同步请求队列。
executorService:线程池
3)ExecutorService线程池
ExecutorService executorService= new ThreadPoolExecutor();
各参数的意义:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue workQueue, ThreadFactory threadFactory)
- corePoolSize 核心线程数,核心线程会一直存活,即使没有任务需要处理。
- maxPoolSize 线程池允许最大的线程数量。
- keepAliveTime 当线程空闲时间达到 keepAliveTime,该线程会退出,直到线程数量等于 corePoolSize。如果allowCoreThreadTimeout 设置为 true,则所有线程均会退出直到线程数量为0。
- allowCoreThreadTimeout 是否允许核心线程空闲keepAliveTime退出,默认值为false。
- workQueue 任务队列。pool.execute(runnable) 提交的 task都 会放到workQueue
4、调用promoteAndExecute方法。
作用:
这个方法的作用是调整异步缓存队列和异步请求队列。通过判断,把任务添加异步请求队列。然后executorService线程池执行AsyncCall的execute方法。
(1)遍历readyAsyncCalls,获取call
(2)判断正在执行的异步请求队列runningAsyncCalls的size是否小于64或同host的小于5,如果满足条件将call添加到正在执行的异步请求队列中,把异步缓存请求队列中的call移除
(3)调用asyncCall.executeOn(executorService())方法
private boolean promoteAndExecute() {
assert (!Thread.holdsLock(this));
List<AsyncCall> executableCalls = new ArrayList<>();
boolean isRunning;
synchronized (this) {
//1、遍历异步缓存请求队列
for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
AsyncCall asyncCall = i.next();
//2、判断异步请求队列的size是否大于64
if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
//3、判断Host是否大于5
if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.
//4、如果满足上述两个条件,从异步缓存请求队列移除call
i.remove();
asyncCall.callsPerHost().incrementAndGet();
executableCalls.add(asyncCall);
//5、把call添加到异步请求队列中
runningAsyncCalls.add(asyncCall);
}
isRunning = runningCallsCount() > 0;
}
for (int i = 0, size = executableCalls.size(); i < size; i++) {
AsyncCall asyncCall = executableCalls.get(i);
//6、调用asyncCall的executeOn方法。
asyncCall.executeOn(executorService());
}
return isRunning;
}
5、调用 asyncCall.executeOn
executeOn作用:
(1)executeOn方法,会调用 executorService.execute(this)方法和dispatcher().finished(this);
(2)executorService.execute(this)方法会利用executorService线程池执行AsyncCall。然后会调用AsyncCall的run方法。在run方法中接着调用拦截器链方法,进行网络数据的获取
(3)dispatcher().finished(this);作用是请求结束后,从异步请求队列移除当前请求,再次调用promoteAndExecute方法,
void executeOn(ExecutorService executorService) {
、、、
boolean success = false;
try {
//1、调用executorService线程池的execute方法,这个方法会调用AsyncCall的run方法
executorService.execute(this);
success = true;
} catch (RejectedExecutionException e) {
、、、
//如果有异常,回调onFailure方法
responseCallback.onFailure(RealCall.this, ioException);
} finally {
if (!success) {
//2、最后,调用dispatcher的finished方法。
client.dispatcher().finished(this); // This call is no longer running!
}
}
}
6、调用 executorService.execute(this);
作用:
executorService是线程池,执行AsyncCall。AsyncCall继承了Runnable,会执行run方法。在run方法中,调用了execute方法。所以当前执行到AsyncCall的execute方法
(1)调用getResponseWithInterceptorChain方法,通过链式调用拦截器获得response,然后回调给responseCallback的onResponse方法。
(2)调用dispatcher的finish方法,从当前队列移除任务,并判断是否执行队列中的下个任务。
@Override protected void execute() {
、、、
try {
//1、调用拦截器链方法
Response response = getResponseWithInterceptorChain();
signalledCallback = true;
responseCallback.onResponse(RealCall.this, response);
} catch (IOException e) {
if (signalledCallback) {
、、、
responseCallback.onFailure(RealCall.this, e);
} catch (Throwable t) {
cancel();
、、、
responseCallback.onFailure(RealCall.this, canceledException);
}
throw t;
} finally {
//最后执行dispatcher的finished方法。
client.dispatcher().finished(this);
}
}
7、dispatcher().finished(this)
作用:
调用dispatcher的finish方法,从当前队列移除任务,并继续调用promoteAndExecute方法,判断是否执行队列中的下个任务。
private <T> void finished(Deque<T> calls, T call) {
Runnable idleCallback;
synchronized (this) {
//1、从对类中移除call
if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
idleCallback = this.idleCallback;
}
//2、调用promoteAndExecute,
//3、isRunning = runningCallsCount() > 0;当前正在执行队列是否大于0
boolean isRunning = promoteAndExecute();
//3、判断回调idleCallback的run方法
if (!isRunning && idleCallback != null) {
idleCallback.run();
}
}
8、RealCall的getResponseWithInterceptorChain()
作用:
1、将我们在OkHttpClient配置的interceptors和五大拦截器添加到集合中。
2、调用RealInterceptorChain的proceed方法,通过链式调用调用拦截器集合中的拦截器,获得response。最终返回给reallCall。
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
//1、添加我们自定义的拦截器,在配置 OkHttpClient 时设置的 interceptors;
interceptors.addAll(client.interceptors());
// 2、负责失败重试以及重定向
interceptors.add(new RetryAndFollowUpInterceptor(client));
//3、请求时,对必要的Header进行一些添加,接收响应时,移除必要的Header
interceptors.add(new BridgeInterceptor(client.cookieJar()));
// 4、负责读取缓存直接返回、更新缓存
interceptors.add(new CacheInterceptor(client.internalCache()));
//5、负责和服务器建立连接
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
//6、配置OkHttpClient 时设置的 networkInterceptors
interceptors.addAll(client.networkInterceptors());
}
//7、负责向服务器发送请求数据、从服务器读取响应数据
interceptors.add(new CallServerInterceptor(forWebSocket));
//这里会初始化RealInterceptorChain,传递为0,设置index为0。
Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0,
originalRequest, this, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
、、、
try {
// 8、使用责任链模式开启链式调用
Response response = chain.proceed(originalRequest);
、、、
}
}
9、RealInterceptorChain的proceed方法
作用:
(1)获取拦截器集合,创建拦截器链RealInterceptorChain,然后通过链式依次调用拦截器。
(2)调用拦截器的intercept方法,之后会回调chain的proceed方法
(3)每调用一个拦截器都会返回response,拦截器集合调用完毕之后,会把response返回给
RealCall的getResponseWithInterceptorChain方法。
public Response proceed() {
//1、index在RealInterceptorChain的构造函数初始化,刚开始为0
if (index >= interceptors.size()) throw new AssertionError();
calls++;
、、、
//这里进行了index + 1
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
index + 1, request, call, connectTimeout, readTimeout, writeTimeout);
//从interceptors获取拦截器,得到当前的拦截器
Interceptor interceptor = interceptors.get(index);
//调用拦截器的intercept方法,并把RealInterceptorChain传递到拦截器中,方便继续调用当前chain的proceed方法。
Response response = interceptor.intercept(next);
//把response返回上一个拦截器,最终会返回给RealCall。
return response;
}
10、拦截器集合
拦截器逻辑总结:
- 在发起请求前对request进行处理
- 调用下一个拦截器,获取response
- 对response进行处理,返回给上一个拦截器
1、我们自定义的DebugInterceptor
通过DebugInterceptor,我们可以实现设置本地json返回数据。在后端接口没有发布的时候,提前进行数据联调。
public class DebugInterceptor implements Interceptor {
private final String DEBUG_URL;
private final int DEBUG_RAW_ID;
private Context mContext;
public DebugInterceptor(String debug_url, int debug_raw_id,Context context) {
DEBUG_URL = debug_url;
DEBUG_RAW_ID = debug_raw_id;
mContext=context;
}
private Response getResponse(Interceptor.Chain chain, String json) {
return new Response.Builder()
.code(200)
.addHeader("Content-Type", "application/json")
.body(ResponseBody.create(MediaType.parse("application/json"), json))
.request(chain.request())
.message("ok")
.protocol(Protocol.HTTP_1_1)
.build();
}
private Response debugResponse(Interceptor.Chain chain, @RawRes int rawId) {
final String json = FileUtils.getRawFile(mContext,rawId);
return getResponse(chain, json);
}
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
final String url = chain.request().url().toString();
if (url.contains(DEBUG_URL)) {
return debugResponse(chain, DEBUG_RAW_ID);
}
return chain.proceed(chain.request());
}
}
2、RetryAndFollowUpInterceptor
作用:重试和重定向拦截器,负责网络请求失败,进行重试。进行重定向。
1、开启一个while (true) 循环
2、调用RealInterceptorChain.proceed进行网络请求,获取response
3、如果有异常,调用continue,终止下面的方法调用,在while (true) 循环中,继续调用2的方法。这里会有一个
4、如果没有异常,对response进行判断,然后return response,跳出while (true) 循环,把response返回给上一个拦截器
5、如果没有return response,这里有一个重试次数的判断,如果超过,会抛出异常。
源码:
@Override public Response intercept(Chain chain) throws IOException {
//1、获取request
Request request = chain.request();
//2、类型强转为RealInterceptorChain
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Transmitter transmitter = realChain.transmitter();
int followUpCount = 0;
Response priorResponse = null;
//3、创建死循环
while (true) {
stream
//4、创建一个strem留来携带request
transmitter.prepareToConnect(request);
、、、
try {
//5、把request和transmitter传递给下一个拦截器,并调用拦截器的intercept方法
response = realChain.proceed(request, transmitter, null);
} catch (Exception e) {
、、、
//如果有异常,继续下一次循环
continue;
} finally {
// The network call threw an exception. Release any resources.
//6、网络有异常,释放资源
if (!success) {
transmitter.exchangeDoneDueToException();
}
}
//7、对response的responseCode返回码进行判断
Request followUp = followUpRequest(response, route);
在下面进行一些判断,如果正常,返回response。
、、、
//8、这里会统计重试的次数,如果大于20次,抛出异常,终止循环。
if (++followUpCount > MAX_FOLLOW_UPS) {
throw new ProtocolException("Too many follow-up requests: " + followUpCount);
}
、、、
}
}
3、BridgeInterceptor
作用:桥接适配拦截器,设置请求内容长度、内容编码、cookie、gzip
1、负责将我们构建的request转化为能够进行网络请求的request,比如添加头部信息。
Content-Type、Content-Length、Transfer-Encoding、Host、Connection=”Keep-Alive”保持长连接,Accept-Encoding、Cookie、User-Agent
2、调用拦截器链的proceed方法,调用下一个拦截器的intercept方法,进行网络请求。
3、将服务器返回的response进行处理,变成我们可以使用的response。比如gzip压缩。
4、CacheInterceptor
作用:负责缓存管理,
1、根据request得到cache中缓存的response
2、当网络请求和缓存为空的时候,抛出504(网关超时)的异常。
3、如果网络请求为空,缓存不为空,直接返回缓存response。
4、调用拦截器链的proceed方法,调用下一个拦截器获取网络数据。
5、如果缓存不为空,对返回的networkResponse的返回码进行判断,如果code是304,那么直接返回缓存,并更新缓存。
6、如果cache为空,对数据进行缓存。
7、判断request,如果为空,将cache中对应的request缓存删除。
@Override public Response intercept(Chain chain) throws IOException {
// 1、根据request得到cache中缓存的response
Response cacheCandidate = cache != null
? cache.get(chain.request())
: null;
long now = System.currentTimeMillis();
// 通过request通过一系列判断创建缓存策略。
request判断缓存的策略,是否要使用了网络,缓存或两者都使用
CacheStrategy strategy = new CacheStrategy.Factory(now, chain.request(), cacheCandidate).get();
Request networkRequest = strategy.networkRequest;
Response cacheResponse = strategy.cacheResponse;
if (cache != null) {
cache.trackResponse(strategy);
}
if (cacheCandidate != null && cacheResponse == null) {
closeQuietly(cacheCandidate.body()); // The cache candidate wasn't applicable. Close it.
}
//当网络请求和缓存为空的时候,抛出504(网关超时)的异常。
if (networkRequest == null && cacheResponse == null) {
return new Response.Builder()
.request(chain.request())
.protocol(Protocol.HTTP_1_1)
.code(504)
.message("Unsatisfiable Request (only-if-cached)")
.body(Util.EMPTY_RESPONSE)
.sentRequestAtMillis(-1L)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
}
// 网络请求为空,直接返回response
if (networkRequest == null) {
return cacheResponse.newBuilder()
.cacheResponse(stripBody(cacheResponse))
.build();
}
Response networkResponse = null;
try {
// 调用下一个拦截器,决定从网络上来得到response
networkResponse = chain.proceed(networkRequest);
} finally {
// If we're crashing on I/O or otherwise, don't leak the cache body.
if (networkResponse == null && cacheCandidate != null) {
closeQuietly(cacheCandidate.body());
}
}
// If we have a cache response too, then we're doing a conditional get.
// 如果本地已经存在cacheResponse,那么让它和网络得到的networkResponse做比较,决定是否来更新缓存的cacheResponse
if (cacheResponse != null) {
//HTTP_NOT_MODIFIED表示304,表示从缓存中获取数据
if (networkResponse.code() == HTTP_NOT_MODIFIED) {
Response response = cacheResponse.newBuilder()
.headers(combine(cacheResponse.headers(), networkResponse.headers()))
.sentRequestAtMillis(networkResponse.sentRequestAtMillis())
.receivedResponseAtMillis(networkResponse.receivedResponseAtMillis())
.cacheResponse(stripBody(cacheResponse))
.networkResponse(stripBody(networkResponse))
.build();
networkResponse.body().close();
// Update the cache after combining headers but before stripping the
// Content-Encoding header (as performed by initContentStream()).
cache.trackConditionalCacheHit();
cache.update(cacheResponse, response);
return response;
} else {
closeQuietly(cacheResponse.body());
}
}
Response response = networkResponse.newBuilder()
.cacheResponse(stripBody(cacheResponse))
.networkResponse(stripBody(networkResponse))
.build();
if (cache != null) {
if (HttpHeaders.hasBody(response) && CacheStrategy.isCacheable(response, networkRequest)) {
// Offer this request to the cache.
// 缓存未经缓存过的response
CacheRequest cacheRequest = cache.put(response);
return cacheWritingResponse(cacheRequest, response);
}
if (HttpMethod.invalidatesCache(networkRequest.method())) {
try {
cache.remove(networkRequest);
} catch (IOException ignored) {
// The cache cannot be written.
}
}
}
return response;
}
5、ConnectInterceptor
网络连接器作用:
1、获取从realChain传递的过来的Transmitter,这个Transmitter是在RetryAndFollowUpInterceptor创建的。
2、通过Transmitter创建exchange,他会携带request和response。在这里我们会获取网络链接,首先判断是否有合适的链接,如果没有我们连接池取,复用已有的链接。如果还是没有,我们会自己创建一个链接RealConnection。然后调用RealConnection的connect方法,进行TCP 和 TLS 握手,这里是难点。
3、调用realChain的proceed方法
@Override public Response intercept(Chain chain) throws IOException {
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Request request = realChain.request();
//1、在RetryAndFollowUpInterceptor我们会创建一个流,现在取出这个流,Transmitter
Transmitter transmitter = realChain.transmitter();
、、、
//2、通过transmitter,我们创建一个exchange,他会携带request和response。
Exchange exchange = transmitter.newExchange(chain, doExtensiveHealthChecks);
//调用realChain的proceed方法
return realChain.proceed(request, transmitter, exchange);
}
//现在重点到transmitter.newExchange方法,这个方法通过一些列判断最终会调用findHealthyConnection。首先开启一个while (true) ,在死循环中调用findConnection方法。
private RealConnection findConnection() throws IOException {
、、、
synchronized (connectionPool) {
、、、
//如果transmitter的connection不为空,我们将它赋值为result
if (transmitter.connection != null) {
// We had an already-allocated connection and it's good.
result = transmitter.connection;
releasedConnection = null;
}
//如果result为空,我们尝试从连接池中国取出一个链接
if (result == null) {
// Attempt to get a connection from the pool.
if (connectionPool.transmitterAcquirePooledConnection(address, transmitter, null, false)) {
foundPooledConnection = true;
result = transmitter.connection;
}
}
}
、、、
//如果还是没有链接,那我们自己创建一个链接
result = new RealConnection(connectionPool, selectedRoute);
//进行 TCP 和 TLS 握手,这是一个耗时操作。这里是重点和难点
result.connect();
、、、
// 将该连接放进连接池中,连接池的实现是队列+线程池。
connectionPool.put(result);
return result;
}
6、CallServerInterceptor
作用:
写入我们的请求头和请求体,然后通过Okio向服务器发出真正的网络请求,读取服务器返回的数据并返回。Okio是另外一个库。真正的IO操作是在Okio进行实现的。
@Override public Response intercept(Chain chain) throws IOException {
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Exchange exchange = realChain.exchange();
Request request = realChain.request();
//通过exchange写入我们的请求头
exchange.writeRequestHeaders(request);
、、
//经过一系列判断,如果是正常的网络请求,会通过Okio进行网络请求
BufferedSink bufferedRequestBody = Okio.buffer(
exchange.createRequestBody(request, true));
//写入我们的请求body
request.body().writeTo(bufferedRequestBody);
}
//停止写入我们的请求信息
if (request.body() == null || !request.body().isDuplex()) {
exchange.finishRequest();
}
//读取我们的response头部
if (responseBuilder == null) {
responseBuilder = exchange.readResponseHeaders(false);
}
//读取我们的response
Response response = responseBuilder
.request(request)
.handshake(exchange.connection().handshake())
.sentRequestAtMillis(sentRequestMillis)
.receivedResponseAtMillis(System.currentTimeMillis())
.build();
exchange.responseHeadersEnd(response);
//接下来会对response的code做一些判断
return response;
}