- RealCall的excute和enqueue分别调用了client.dispatcher的excute和enqueue方法,而dispatcher中为同步和异步的请求维护了三个先进先出数组
- interceptor执行的顺序
val interceptors = mutableListOf<Interceptor>()
//此处是用户自己的拦截器,对应addInterceptor()每次发起请求都会第一个调用,可以用来统计用户发起请求的次数
interceptors += client.interceptors
/**
* This interceptor recovers from failures and follows redirects as necessary. It may throw an
* [IOException] if the call was canceled.
*/
interceptors += RetryAndFollowUpInterceptor(client)
/**
* 应用层和网络层的桥接拦截器,主要工作是为请求添加cookie、添加固定的header,
比如Host、Content-Length、Content-Type、User-Agent等等,然后保存响应结果的cookie,如
果响应使用gzip压缩过,则还需要进行解压。
*/
interceptors += BridgeInterceptor(client.cookieJar)
/** Serves requests from the cache and writes responses to the cache. */
interceptors += CacheInterceptor(client.cache)
/**
* Opens a connection to the target server and proceeds to the next interceptor. The network might
* be used for the returned response, or to validate a cached response with a conditional GET.
*/
interceptors += ConnectInterceptor
if (!forWebSocket) {
//此处对应的是addNetworkInterceptor(),每次发次网络请求都会调用
interceptors += client.networkInterceptors
}
/** This is the last interceptor in the chain. It makes a network call to the server. */
interceptors += CallServerInterceptor(forWebSocket)
- chain按顺序执行代码
// Call the next interceptor in the chain.
//copy()返回一个新的RealInterceptorChain
val next = copy(index = index + 1, request = request)
val interceptor = interceptors[index]
@Suppress("USELESS_ELVIS")
val response = interceptor.intercept(next) ?: throw NullPointerException(
"interceptor $interceptor returned null")
- cacheInterceptor
- 内置封装了一个Cache类,它利用DiskLruCache,用磁盘上的有限大小空间进行缓存,按照 LRU 算法进行缓存淘汰
- okhttp主要是利用了http的缓存机制,具体可看这里
第一次拿到响应后根据头信息决定是否缓存。
下次请求时判断是否存在本地缓存,是否需要使用对比缓存、封装请求头信息等等。
如果缓存失效或者需要对比缓存则发出网络请求,否则使用本地缓存。