导言

Android 开发的国际中,有一些组件,不管运用层技能再怎样迭代,作为根底支撑,它们仍然在那里。 比方当咱们提到网络库时,总会下意识想到一个姓名,即 OkHttp

尽管关于大多数开发者而言,通常状况下运用的是往往它的封装版本 Retrofit ,不过其底层仍然离不开 Okhttp 作为根底支撑。而不管是自研网络库的二次封装,仍是个人运用,OkHttp 也往往都是不贰之选。

故本篇将以最新视角开端,用力一瞥 OkHttp 的规划魅力。

本文对应的 OkHttp 版本: 4.10.0

本篇定位 中高难度,将从布景到运用办法,再到规划思维与源码解析,尽可能全面、易懂。

布景

每一个技能都有其变迁的前史布景与特性,本末节,咱们将聊一聊 Android网络库 的迭代史,作为开篇引语,润润眼。

关于 Android网络库 的迭代前史,如下图所示:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

详细进展如下:

  • HttpClient

    Android1.0 时推出。但存在诸多问题,比方内存泄漏,频频的GC等。5.0后,已被弃用;

  • HttpURLConnection

    Android2.2 时推出,比 HttpClient 更快更安稳,Android4.4 之后底层现已被 Okhttp 代替;

  • volley

    Google 2013年开源,基于 HttpURLConnection 的封装,具有良好的扩展性和适用性,不过关于杂乱恳求或许很多网络恳求时,功能较差。现在仍然有不少项目运用(通常是老代码的保护);

  • okhttp

    Square 2013年开源,基于 原生Http 的底层规划,具有 快速安稳节约资源 等特色。是现在诸多热门网络恳求库的底层完结,比方 RetrofitRxHttp 等;

  • Retrofit

    Square 2013年开源,基于 OkHttp 的封装,现在 干流 的网络恳求库。

    经过注解办法装备网络恳求、REST风格 api、解耦完全、经常会调配 Rx等 完结 结构联动;

上述的整个进程,也正是伴随了 Android 开发的各个时期,假如将上述分为 5个阶段 的话,那么则为:

HttpClient -> HttpURLConnection -> volley -> okhttp -> Retrofit*

经过 Android网络库 的迭代前史,咱们不难发现,技能变迁越来越趋于安稳,而 OkHttp 也现已成为了根底组件中不行所缺的一员。

规划思维

当聊到OkHttp的规划思维,咱们想知道什么?

运用层去看,娴熟的开发者会直接喊出阻拦器,巴拉巴拉…

而作为初学者,可能更期望的事广度与解惑,OkHttp 究竟牛在了什么地方,或许说常说的 阻拦器究竟是什么 ?

在官方的描述中,OkHttp 是一个高效的 Http恳求结构 ,旨在 简化 客户端网络恳求,进步 恳求功率。

详细规划思维与特性如下:

  • 衔接复用 :防止在每个恳求之间从头树立衔接。
  • 衔接池 降低了恳求延迟 (HTTP/2不行用状况下);
  • 主动重试 :在恳求失利时主动重试恳求,然后进步恳求可靠性。
  • 主动处理缓存 :会依照预定的缓存战略处理缓存,以便最大化网络功率。
  • 支撑HTTP/2, 而且允许对同一个主机的一切恳求同享一个套接字(HTTP/2);
  • 简化Api:Api规划简略明了,易于运用,能够轻松建议恳求获取呼应,并处理反常。
  • 支撑gzip紧缩 :OkHttp支撑gzip紧缩,以便经过削减网络数据的巨细来进步网络功率。

特别的,假如咱们的服务器或许域名有 多个IP地址OkHttp 将在 第一次 衔接失利时测验代替原有的地址(关于 IPv4+IPv6 和保管在冗余数据中心的服务是必需的)。而且支撑现代 TLS 功能(TLS 1.3、ALPN、证书固定)。它能够装备为回退以完结广泛的衔接。

总的来说,其规划思维是经过 简化恳求进程进步恳求功率进步恳求可靠性,然后供给 更快的呼应速度

运用层的整个恳求结构图如下:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

运用办法

在开端探究规划原理与思维之前,咱们仍是要先看看最根底的运用办法,以便为后续做一些铺垫。

// build.gradle
implementation "com.squareup.okhttp3:okhttp:4.10.0"
// Android Manifest
<uses-permission android:name="android.permission.INTERNET" />

建议一个get恳求

由浅入深,聊聊OkHttp的那些事(很长,很细节)

阻拦器的运用

由浅入深,聊聊OkHttp的那些事(很长,很细节)

总结起来便是下面几步:

  1. 创立 OkHttpClient 目标;
  2. 构建 Request ;
  3. 调用 OkHttpClient 履行 request 恳求 ;
  4. 同步堵塞 或许 异步回调 办法接纳成果;

更多运用办法,能够在查找其他同学的教程,这儿仅仅仅仅作为后续解析原理时的必要根底支撑。

源码剖析

根底装备

OkHttpClient

val client = OkHttpClient.Builder().xxx.build()

由上述调用办法,咱们便能够猜出,这儿运用了 构建者形式 去装备默许的参数,所以直接去看 OkHttpClient.Builder 支撑的参数即可,详细如下:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

详细的属性意思在代码中也都有注释,这儿咱们就不在多提了。

需求留意的是,在运用进程中,关于 OkHttpClient 咱们仍是应该缓存下来或许运用单例形式以便后续复用,由于其相对而言仍是比较重。


Request

指客户端发送到服务器的 HTTP恳求

OkHttp 中,能够运用 Request 目标来构建恳求,然后运用 OkHttpClient 目标来发送恳求。 通常状况下,一个恳求包括了 恳求头恳求办法恳求途径恳求参数url地址 等信息。首要是用来恳求服务器回来某些资源,如网页、图片、数据等。

详细源码如下所示:

Request.Builder().url("https://www.baidu.com").build()
open class Builder {
  // url地址
  internal var url: HttpUrl? = null		 	
  // 恳求办法
  internal var method: String					 			
  // 恳求头
  internal var headers: Headers.Builder		 			
  // 恳求体
  internal var body: RequestBody? = null	 			
  // 恳求tag
  internal var tags: MutableMap<Class<*>, Any>  	
}

建议恳求

execute()

用于履行 同步恳求 时调用,详细源码如下:

client.newCall(request).execute()

接下来咱们再去看看 client.newCall() , 即恳求建议时的逻辑。

由浅入深,聊聊OkHttp的那些事(很长,很细节)

当咱们运用 OkHttpClient.newCall() 办法时,实践是创立了一个新的 RealCall 目标,用于 运用层与网络层之间的桥梁,用于处理衔接、恳求、呼应以及流 ,其默许构造函数中需求传递 okhttpClient 目标以及 request

接着,运用了 RealCall 目标调用了其 execute() 办法开端建议恳求,该办法内部会将当时的 call 参加咱们 Dispatcher 分发器内部的 runningSyncCalls 行列中取,等候被履行。接着调用 getResponseWithInterceptorChain() ,运用阻拦器获取本次恳求呼应的内容,这也即咱们接下来要重视的进程。


enqueue()

履行 异步恳求 时调用,详细源码如下:

client.newCall(request).enqueue(CallBack)

由浅入深,聊聊OkHttp的那些事(很长,很细节)

当咱们调用 RealCall.enqueue() 履行异步恳求时,会先将本次恳求参加 Dispather.readyAsyncCalls 行列中等候履行,假如当时恳求是 webSocket 恳求,则查找与当时恳求是同一个 host 的恳求,假如存在共同的恳求,则复用先前的恳求。

接下来调用 promoteAndExecute() 将一切符合条件能够恳求的 Call 从等候行列中增加到 可恳求行列 中,再遍历该恳求行列,将其增加到 线程池 中去履行。

继续沿着上面的源码,咱们去看 asyncCall.executeOn(executorService) ,如下所示:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述逻辑也很简略,当咱们将任务增加到线程池后,当任务被履行时,即触发 run() 办法的调用。该办法中会去调用 getResponseWithInterceptorChain() 然后运用阻拦器链获取服务器呼应,然后完结本次恳求。恳求成功后则调用咱们开端时的 callback目标 的 onResponse() 办法,反常(即失利时)则调用 onFailure() 办法。


阻拦器链

在上面咱们知道,他们终究都走到了 RealCall.getResponseWithInterceptorChain() 办法,即运用 阻拦器链 获取本次恳求的呼应内容。不过关于初看OkHttp源码的同学,这一步运用会有点迷惑,阻拦器链 是什么东东?

在解说 阻拦器链 之前,咱们不妨先看一下 RealCall.getResponseWithInterceptorChain() 办法对应的源码完结,然后再去解说为什么,或许更简略了解。

详细源码如下:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述的逻辑十分简略,内部会先创立一个部分阻拦器调集,然后将咱们自己设置的一般阻拦器增加到该调集中,然后增加中心的5大阻拦器,接着再将咱们自定义的网络阻拦器也增加到该调集中,终究才增加了真实用于履行网络恳求的阻拦器。接着创立了一个阻拦器职责链 RealInterceptorChain ,并调用其 proceed() 办法开端履行本次恳求。


职责链形式

在上面咱们说到了,要解说 OkHttp 的阻拦器链,咱们有必要简略聊一下什么是职责链形式?

职责链形式(Chain of Responsibility)是一种处理恳求的形式,它让多个处理器都有机会处理该恳求,直到其间某个处理成功停止。职责链形式把多个处理器串成链,然后让恳求在链上传递。

摘自 职责链形式 @廖雪峰

Android 中常见的事情分发为例:当咱们的手指点击屏幕开端,用户的触摸事情从 Activity 开端分发,接着从 windows 开端分发到详细的 contentView(ViewGroup) 上,开端调用其 dispatchTouEvent() 办法进行事情分发。在这个办法内,假如当时 ViewGroup 不进行阻拦,则默许会继续向下分发,寻觅当时 ViewGroup 下对应的触摸方位 View ,假如该 View 是一个 ViewGroup ,则重复上述进程。假如事情被某个 view 阻拦,则触发其 onTouchEvent() 办法,接着交由该view去消费该事情。而假如事情传递到最上层 view 仍是没人消费,则该事情开端依照原路回来,先交给当时 view 自己的 onTouchEvent() ,由于自己不消费,则调用其 父ViewGrouponTouchEvent() ,如此层层传递,终究又交给了 Act 自行处理。上述这个流程,便是 职责链形式 的一种表现。

如下图所示:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上图来自 Android事情分发机制三:事情分发作业流程 @一只修仙的猿


看完什么是职责链形式,让咱们将思路转回到 OkHttp 上面,咱们再去看一下 RealInterceptorChain 源码。

由浅入深,聊聊OkHttp的那些事(很长,很细节)

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述逻辑如下:

  • getResponseWithInterceptorChain() 办法内部终究调用 RealInterceptorChain.proceed() 时,内部传入了一个默许的index ,这个 index 就代表了当时要调用的 阻拦器item ,并在办法内部每次创立一个新的 RealInterceptorChain 链,index+1,再调用当时阻拦器 intercept() 办法时,然后将下一个链传入;

  • 最开端调用的是用户自定义的 一般阻拦器,假如上述咱们增加了一个 CustomLogInterceptor 的阻拦器,当获取 response 时,咱们需求调用 Interceptor.Chain.proceed() ,而此刻的 chain 正是下一个阻拦器对应的 RealInterceptorChain

  • 上述流程里,index从0开端,以此类推,一直到链条末尾,即 阻拦器调集长度-1处;

  • 当遇到终究一个阻拦器 CallServerInterceptor 时,此刻由于现已是终究一个阻拦器,链条必定要完毕了,所以其内部必定也不会调用 proceed() 办法。

    相应的,为什么咱们在前面说 它 是真实履行与服务器树立实践通讯的阻拦器?

    由于这个里会获取与服务器通讯的 response ,即最初呼应成果,然后将其回来上一个阻拦器,即咱们的网络阻拦器,再接着又向上回来,终究回来到咱们的一般阻拦器处,然后完结整个链路的路由

参照上面的流程,即大致思路图如下:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

阻拦器

RetryAndFollowUpInterceptor

见名知意,用于 恳求失利重试 作业以及 重定向 的后续恳求作业,一起还会对 衔接 做一些初始化作业。

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述的逻辑,咱们分为四段进行剖析:

  1. 恳求时假如遇到反常,则依据状况去测验康复,假如不能康复,则抛出反常,越过本次恳求;假如恳求成功,则在 finally 里开释资源;
  2. 假如恳求是重试之后的恳求,那么将重试前恳求的呼应体设置为null,并增加到当时呼应体的 priorResponse 字段中;
  3. 依据当时的responseCode判别是否需求重试,若不需求,则回来 response ;若需求,则回来 request ,并在后续查看当时重试次数是否达到阈值;
  4. 重复上述进程,直到进程三成功。

在第一步时,获取 response 时,需求调用 realChain.proceed(request) ,假如你还记得上述的职责链,所以这儿触发了下面的阻拦器履行,即 BridgeInterceptor


BridgeInterceptor

用于 客户端和服务器 之间的交流 桥梁 ,担任将用户构建的恳求转换为服务器需求的恳求。比方增加 content-typecookie 等,再将服务器回来的 response 做一些处理,转换为客户端所需求的 response,比方移除 Content-Encoding ,详细见下面源码所示:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述逻辑如下:

  1. 首要调用 chain.request() 获取原始恳求数据,然后开端从头构建恳求头,增加 header 以及 cookie 等信息;
  2. 将第一步构建好的新的 request 传入 chain.proceed() ,然后触发下一个阻拦器的履行,并得到 服务器回来的 response。然后保存 response 带着的 cookie,并移除 header 中的 Content-EncodingContent-Length,并同步修正 body

CacheInterceptor

见名知意,其用于网络缓存,开发者能够经过 OkHttpClient.cache() 办法来装备缓存,在底层的完结处,缓存阻拦器经过 CacheStrategy 来判别是运用网络仍是缓存来构建 response。详细的 cache 战略采用的是 DiskLruCache

Cache的战略如下图所示:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

详细源码如下所示:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

详细的逻辑如上图所示,详细能够参照上述的 Cache 流程图,这儿咱们再说一下 CacheStrategy 这个类,即决议何时运用 网络恳求、呼应缓存。

CacheStrategy

由浅入深,聊聊OkHttp的那些事(很长,很细节)


ConnectInterceptor

完结与服务器真实的衔接。

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述流程如下:

  • 初始化 一个 exchange 目标;
  • 依据 exchange 目标来仿制创立一个新的衔接职责链;
  • 履行该衔接职责链。

那 Exchange 是什么呢?

在官方的解说里,其用于 传递单个 HTTP 恳求和呼应对,在 ExchangeCode 的根底上背负了一些办理及事情分发的作用。

详细而言,ExchangeRequest 相对应,新建一个恳求时就会创立一个 Exchange,该 Exchange 担任将这个恳求发送出去并读取到呼应数据,而详细的发送与接纳数据运用的则是 ExchangeCodec

相应的,ExchangeCode 又是什么呢?

ExchangeCodec 担任对 request 编码及解码 Response ,即写入恳求及读取呼应,咱们的恳求及呼应数据都是经过它来读写。

通俗一点便是,ExchangeCodec 是恳求处理器,它内部封装了 OkHttp 中履行网络恳求的细节完结,其经过接受一个 Request 目标,并在内部进行处理,终究生成一个符合 HTTP 协议标准的网络恳求,然后接受服务器回来的HTTP呼应,并生成一个 Response 目标,然后完结网络恳求的整个进程。

额外的,咱们还需求再提一个类,ExchangeFinder

用于寻觅可用的 Exchange ,然后发送下一个恳求并接受下一个呼应。

虽然上述流程看起来似乎很简略,但咱们仍是要剖析下详细的流程,源码如下所示:

RealCall.initExchange()

初始化 Exchage 的进程。

ExchangeFinder 找到一个新的或许现已存在的 ExchangeCodec,然后初始化 Exchange ,以此来承载接下来的HTTP恳求和呼应对。

由浅入深,聊聊OkHttp的那些事(很长,很细节)


ExchangeFinder.find()

查找 ExchangeCodec(恳求呼应编码器) 的进程。

由浅入深,聊聊OkHttp的那些事(很长,很细节)

接下来咱们看看查找 RealConnection 的详细进程:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述的整个流程如下:

上述会先经过 ExchangeFinderRealConnecionPool 中测验寻觅现已存在的衔接,未找到则会从头创立一个 RealConnection(衔接) 目标,并将其增加到衔接池里,开端衔接。然后依据找到或许新创立 RealConnection 目标,并依据当时恳求协议创立不同的 ExchangeCodec 目标并回来,终究初始化一个 Exchange 交换器并回来,然后完结了 Exchange 的初始化进程。

在详细找寻 RealConnection 的进程中,一共测验了5次,详细如下:

  1. 测验重连 call 中的 connection,此刻不需求从头获取衔接;
  2. 测验从衔接池中获取一个衔接,不带路由与多路复用;
  3. 再次测验从衔接池中获取一个衔接,带路由,不带多路复用;
  4. 手动创立一个新衔接;
  5. 再次测验从衔接池中获取一个衔接,带路由与多路复用;

Exchange 初始化完结后,再仿制该目标创立一个新的 Exchange ,并履行下一个职责链,然后完结衔接的树立。


networkInterceptors

网络阻拦器,即 client.networkInterceptors 中自定义阻拦器,与一般的阻拦器 client.interceptors 不同的是:

由于网络阻拦器处于倒数第二层,在 RetryAndFollowUpInterceptor 失利或许 CacheInterceptor 回来缓存的状况下,网络阻拦器无法被履行。而一般阻拦器由于第一步就被就履行到,所以不受这个约束。


CallServerInterceptor

链中的终究一个阻拦器,也即与服务器进行通讯的阻拦器,利用 HttpCodec 进行数据恳求、呼应数据的读写。

详细源码如下:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

先写入要发送的恳求头,然后依据条件判别是否写入要发送的恳求体。当恳求完毕后,解析服务器回来的呼应头,构建一个新的 response 并回来;假如 response.code100,则从头读取呼应体并构建新的 response。由于这是最底层的阻拦器,所以这儿必定不会再调用 proceed() 再往下履行。

小结

至此,关于 OkHttp 的剖析,到这儿就完毕了。为了便于了解,咱们再串一遍整个思路:

OkHttp 中,RealCallCall 的完结类,其担任 履行网络恳求 。其间,恳求 requestDispatcher 进行调度,其间 异步调用 时,会将恳求放到到线程池中去履行; 而同步的恳求则仅仅会增加到 Dispatcher 中去办理,并不会有线程池参与协调履行。

在详细的恳求进程中,网络恳求依次会经过下列阻拦器组成的职责链,终究发送到服务器。

  1. 一般阻拦器,client.interceptors()
  2. 重试、重定向阻拦器 RetryAndFollowUpInterceptor
  3. 用于客户端与服务器桥梁,将用户恳求转换为服务器恳求,将服务器呼应转换为用户呼应的的 BridgeInterceptor
  4. 决议是否需求恳求服务器并写入缓存再回来仍是直接回来服务器呼应缓存的 CacheInterceptor;
  5. 与服务器树立衔接的 ConnectInterceptor
  6. 网络阻拦器,client.networkInterceptors();
  7. 履行网络恳求的 CallServerInterceptor;

而相应的服务器呼应体则会从 CallServerInterceptor 开端依次往前开端回来,终究由客户端进行处理。

需求留意的是,当咱们 RetryAndFollowUpInterceptor 反常或许 CacheInterceptor 阻拦器直接回来了有用缓存,后续的阻拦器将不会履行。

常见问题

OkHttp怎么判别缓存有用性?

这儿其实首要说的是 CacheInterceptor 阻拦器里的逻辑,详细如下:

OkHttp 运用 HTTP协议 中的 缓存操控机制 来判别缓存是否有用。假如恳求头中包括 "Cache-Control""If-None-Match" / "If-Modified-Since" 字段,OkHttp 将依据这些字段的值来决议是否运用缓存或从网络恳求呼应。

Cache-Control 指 包括缓存操控的指令,例如 “no-cache”“max-age” ;

If-None-Match 指 客户端缓存的呼应的ETag值,假如服务器回来相同的 ETag 值,则阐明呼应未修正,缓存有用;

If-Modified-Since 指 客户端缓存的呼应的终究修正时刻,假如服务器确认呼应在此刻间后未更改,则回来304 Not Modified状况码,表示缓存有用。

相应的,OkHttp 也支撑自定义缓存有用性操控,开发者能够创立一个 CacheControl 目标,并将其作为恳求头增加到 Request 中,如下所示:

// 禁止OkHttp运用缓存
val cacheControl = CacheControl.Builder()
            .noCache()
            .build()
val request = Request.Builder()
            .cacheControl(cacheControl)
            .url("https://www.baidu.com")
            .build()

OkHttp怎么复用TCP衔接?

这个其实首要说的是 ConnectInterceptor 阻拦器中初始化 Exchange 时内部做的事,详细如下:

OkHttp 运用衔接池 RealConnectionPool 办理一切衔接,衔接池将一切活动的衔接存储在池中,并保护了一个空闲的衔接列表(TaskQueue),当需求新的衔接时,优先测验从这个池中找,假如没找到,则 从头创立 一个 RealConnection 衔接目标,并将其增加到衔接池中。在详细的寻觅衔接的进程中,一共进行了下面5次测验:

  1. 测验重连 RealCall 中的 connection,此刻不需求从头获取衔接;
  2. 测验从衔接池中获取一个衔接,不带路由与多路复用;
  3. 再次测验从衔接池中获取一个衔接,带路由,不带多路复用;
  4. 手动创立一个新衔接;
  5. 再次测验从衔接池中获取一个衔接,带路由与多路复用;

当然 OkHttp 也支撑自定义衔接池,详细如下:

由浅入深,聊聊OkHttp的那些事(很长,很细节)

上述代码中,创立了一个新的衔接池,并设置其保存最多 maxIdleConnections 个空闲衔接,而且衔接的存活期为 keepAliveDuration 分钟。

OKHttp复用TCP衔接的好处是什么?

OkHttp 是由衔接池办理一切衔接,经过衔接池,然后能够约束衔接的 最大数量,而且关于空闲的衔接有相应的 存活期限 ,以便在长时刻不运用后封闭衔接。当恳求完毕时,而且将保存该衔接,便于后续 复用 。然后完结了在多个恳求之间同享衔接,防止屡次树立和封闭TCP衔接的开支,进步恳求功率。

OkHttp中的恳求和呼应 与 网络恳求和呼应,这两者有什么不同?

OkHttp 中的的恳求和呼应指的是客户端创立的恳求目标 Request 和 服务端回来的呼应目标 Response,这两个目标用于定义恳求和呼应的信息。网络恳求和呼应指的是客户端向服务端发送恳求,服务端回来相应的进程。

总的来说便是,恳求和呼应是运用程序内部自己的事,网络恳求和呼应则是产生在网络上的恳求和呼应进程

OkHttp 运用阻拦器和网络阻拦器的区别?

  • 从调用办法上而言,运用阻拦器指的是 OkhttpClient.intercetors ,网络阻拦器指的是 OkHttpClient.netIntercetors
  • 从整个职责链的调用来看,运用阻拦器一定会被履行一次,而网络阻拦器不一定会履行或许履行屡次状况,比方当咱们 RetryAndFollowUpInterceptor 反常或许 CacheInterceptor 阻拦器直接回来了有用缓存,后续的阻拦器将不会履行,相应的网络阻拦器也天然不会履行到;当咱们产生 错误重试 或许 网络重定向 时,网络阻拦器此刻可能就会履行屡次。
  • 其次,除了 CallServerInterceptorCacheIntercerceptor 缓存有用之外,每个阻拦器都应该至少调用一次 realChain.proceed() 办法。但运用阻拦器能够调用屡次 processed() 办法,由于其在恳求流程中是能够递归调用;而网络阻拦器只能调用一次 processed() 办法,否则将导致恳求重复提交,影响功能,别的,网络阻拦器没有对恳求做修正的可能性,因而不需求再次调用 processed() 办法。
  • 运用办法的 实质而言,运用阻拦器能够 阻拦和修正恳求和呼应 ,但 不能修正网络恳求和呼应 。比方运用运用阻拦器增加恳求参数、缓存恳求成果;网络阻拦器能够阻拦和修正网络恳求和呼应。例如运用网络阻拦器增加恳求头、修正恳求内容、查看呼应码等。
  • 在相应的履行次序上,网络阻拦器是 先进先出(FIFO) ,运用阻拦器是 先进后出(FILO) 的办法履行。

结语

本篇中,咱们从网络库的迭代前史,一直到 OkHttp 的运用办法、规划思维、源码探究,终究又聊了聊常见的一些问题,然后较体系的了解了 OkHttp 的方方面面,也解说了 OkHttp运用层 的相关问题,当然这些问题我信任也仅仅仅仅冰山一角。 更多面试相关,或许实践问题,仍需求咱们自己再进行完善,然后形成全面的透析力。

这篇文章断断续续写了将近两周,其间必定有不少部分存在缺点或许逻辑漏洞,假如您发现了,也能够告诉我。

经过这篇文章,于我个人而言,也是完结了关于 OkHttp运用层 一次较体系的了解,然后也完善了常识拼图中重要的一块,等待作为读者的你也能有如此或许更深的体会。

更多

这是 解码系列 – OkHttp 篇,假如你觉得这个系列写的还不错,不妨点个重视催更一波,当然也能够看看其他篇:

  • 由浅入深,详解 Lifecycle 的那些事
  • 由浅入深,详解 LiveData 的那些事
  • 由浅入深,详解 ViewModel 的那些事
  • 由浅入深,详解 LeakCanary 的那些事

参看

  • 深入了解OkHttp源码及规划思维
  • OkHttp源码走心解析(很细 很长)
  • 拆轮子系列:拆 OkHttp
  • OkHttp 源码剖析

关于我

我是 Petterp ,一个 Android工程师 ,假如本文对你有所协助,欢迎 点赞、评论、收藏,你的支撑是我继续创作的最大鼓励!