?? ?1. newCall(Request)方法会返回一个RealCall对象,它是Call接口的实现。当调用 RealCall.execute() 的时候,RealCall.getResponseWithInterceptorChain()会被调用,它会发起网络请求并拿到返回的响应,装进一个Response对象并作为返回值返回;RealCall.enqueue()被调用的时候大同小异,区别在于enaueue()会使用Dispatcher的线程池来把请求放在后台线程进行,但实质上使用的同样也是 getResponseWithInterceptorChain()方法。? ?? ?2. getResponseWithInterceptorChain()方法做的事:把所有配置好的 Interceptor放在一个List里,然后作为参数,创建一个RealInterceptorChain对象,并调用chain.proceed(request)来发起请求和获取响应。 ?? ?3. 在RealInterceptorChain中,多个 Interceptor会依次调用自己的intercept()方法。这个方法会做三件事: ?? ?当然了,最后一个Interceptor的任务只有一个:做真正的网络请求并拿到响应 ?? ??? ?a. 1.对请求进行预处理 ?? ??? ?b. 2、预处理之后,重新调用RealIntercepterChain.proceed()把请求交给下一个Interceptor ?? ??? ?c. 3、在下一个Interceptor处理完成并返回之后,拿到Response进行后续处理 ?? ?4. 从上到下,每级Interceptor 做的事: ?? ??? ?a. o首先是开发者使用 addInterceptor(Interceptor) 所设置的,它们会按照开发者的要求,在所有其他Interceptor处理之前,进行最早的预处理工作,以及在收到Response之后,做最后的善后工作。如果你有统一的header要添加,可以在这里设置; ?? ??? ?b. o然后是RetryAndFollowUpInterceptor:它会对连接做一些初始化工作,并且负责在请求失败时的重试,以及重定向的自动后续请求。它的存在,可以让重试和重定向对于开发者是无感知的; ?? ??? ?c. BridgeInterceptor:它负责一些不影响开发者开发,但影响HTTP交互的一些额外预处理。例如,Content-Length的计算和添加、gzip的支持 (Accept-Encoding: gzip)、gzip压缩数据的解包,都是发生在这里; ?? ??? ?d. o CacheInterceptor:它负责Cache的处理。把它放在后面的网络交互相关Interceptor的前面的好处是,如果本地有了可用的Cache,一个请求可以在没有发生实质网络交互的情况下就返回缓存结果,而完全不需要开发者做出任何的额外工作,让Cache更加无感知; ?? ??? ?e. oConnectInterceptor:它负责建立连接。在这里,OkHttp会创建出网络请求所需要的TCP连接(如果是HTTP),或者是建立在TCP连接之上的TLS连接(如果是HTTPS),并且会创建出对应的HttpCodec对象(用于编码解码HTTP请求); ?? ??? ?f. 然后是开发者使用addNetworkInterceptor(Interceptor)所设置的,它们的行为逻辑和使用addInterceptor(Interceptor)创建的一样,但由于位置不同,所以这里创建的Interceptor会看到每个请求和响应的数据(包括重定向以及重试的一些中间请求和响应),并且看到的是完整原始数据,而不是没有加Content-Length的请求数据,或者Body还没有被gzip解压的响应数据。多数情况,这个方法不需要被使用,不过如果你要做网络调试,可以用它; ?? ??? ?g. o CallServerInterceptor:它负责实质的请求与响应的I/0操作,即往Socket里写入请求数据,和从Socket里读取响应数据。
?
|