文章目录
- OkHttp
- 概要
- 1.简介
- 2.特点
- 3.基本组成
- 5.工作流程
- 拦截器
- 1.简介
- 2.内置拦截器
- 3.自定义拦截器
- 连接池
- 1.简介
- 2.常用参数配置选项
- Dispatcher和线程池
- 1.简介
- 2.重要方法
- 3.DispatCher中的双端队列
- 4.总结
OkHttp
概要
1.简介
- OkHttp是一个开源的HTTP客户端,用于在Java和Android应用程序中发送HTTP请求。
- 是一个支持 HTTP 和 HTTP/2 的封装的网络请求客户端。
2.特点
- 高效的连接复用:OkHttp可以复用现有的TCP连接,减少建立和关闭连接的开销,提高性能。
- 支持HTTP/2:OkHttp支持最新的HTTP/2协议,能够提高传输速度和减少延迟。
- 灵活的配置:用户可以配置各种请求参数,如超时时间、重定向策略、缓存策略等。
- 强大的拦截器机制:通过拦截器,可以在请求发送和响应接收的过程中插入自定义逻辑,非常适合进行日志记录、添加认证等操作。
- 简单的API:OkHttp提供了简单易用的API,使得发送请求和处理响应变得十分方便。
- 支持同步和异步请求:用户可以选择同步或异步地发送HTTP请求,以适应不同的应用场景。
3.基本组成
-
请求(Request)和响应(Response):
OkHttp中的每个请求和响应都封装了HTTP协议的所有必要信息,包括方法(如GET、POST)、URL、头部(Headers)、正文(Body)等。 -
客户端(Client):
客户端是OkHttp的核心,负责创建请求、管理连接、执行请求并处理响应。它提供了多种配置选项,如超时时间、重定向策略、协议版本等。 -
连接管理器(ConnectionPool):
连接管理器负责维护一个连接池,用于复用TCP连接。这样可以减少建立和关闭连接的次数,提高性能。 -
拦截器(Interceptor):
拦截器是一个可以在请求发送到服务器之前和响应从服务器返回之后修改请求或响应的组件。它们通常用于添加认证、日志记录、请求头修改等。 -
事件日志(EventListener):
事件日志用于记录请求和响应的生命周期事件,如连接创建、响应接收等。这有助于调试和监控网络活动。
同步/异步执行:
OkHttp支持同步和异步执行请求。同步请求会阻塞当前线程直到请求完成,而异步请求则使用回调在后台线程中处理结果。 -
缓存(Cache):
OkHttp支持HTTP缓存,可以缓存响应以供后续请求重用,减少网络延迟和数据量传输。 -
协议解析器(Protocols):
OkHttp支持多种HTTP协议版本,如HTTP/1.1和HTTP/2。协议解析器负责解析传入的网络数据,并将其转换为可处理的响应对象。 -
SSL/TLS加密:
OkHttp支持通过SSL/TLS对网络连接进行加密,以确保数据传输的安全性。 -
错误处理:
OkHttp提供了错误处理机制,能够处理网络问题、超时、解析错误等各种异常情况。OkHttp 主要是通过 5 个拦截器和 3 个双端队列(2 个异步队列,1 个同步队列)工作。
内部实现通过一个责任链模式完成,将网络请求的各个阶段封装到各个链条中,实现了各层的解耦。
底层通过 Socket 发送 HTTP 请求与接受响应,并实现了连接池的概念。
5.工作流程
-
通过构建者构建出OkHttpClient对象,通过newCall方法获得RealCall请求对象,发起同步或异步请求。
-
通过Dispatcher对我们所有的RealCall(Call的具体实现类)进行统一管理,处理同步或异步请求。
-
通过拦截器对请求依次处理,与服务的建立连接后,获取返回数据,再经过上述拦截器依次处理,最后将结果返回给调用方。
拦截器
1.简介
- 允许开发者在请求发送到服务器之前和响应从服务器返回之后对请求或响应进行修改。
- 五个内置拦截器按顺序组成一个拦截器链,每个拦截器都可以选择处理请求或响应,或者传递给下一个拦截器。
- 此外,开发者还可以自定义拦截器,插入到这个拦截器链中的适当位置,以便能够处理请求或响应的相应部分。
2.内置拦截器
-
RetryAndFollowUpInterceptor:
这个拦截器负责处理重定向和重新尝试逻辑。如果原始请求因为某些原因(如网络问题)失败了,它会尝试再次发送请求。此外,如果服务器响应了一个重定向,这个拦截器也会处理后续的请求。 -
CacheInterceptor:
缓存拦截器负责处理HTTP缓存。在发送实际的网络请求之前,它会检查本地缓存是否有响应的副本,如果有,则返回缓存版本而不是发起网络请求。同样,当响应被返回时,它会将响应缓存到本地。 -
ConnectInterceptor:
连接拦截器在建立连接时被调用。它负责创建和管理与服务器的TCP连接。如果请求需要建立一个全新的连接,这个拦截器会处理连接的创建。 -
CallServerInterceptor:
这个拦截器是处理实际请求和接收响应的。它将请求发送到服务器,并接收服务器的响应。这是请求生命周期中的最后一个拦截器。 -
BridgeInterceptor:
桥接拦截器位于连接拦截器和调用服务器拦截器之间。它的主要作用是处理一些特殊情况,比如在HTTPS请求中,将原始的HTTP请求转换为HTTPS请求。此外,它还负责在请求中添加一些必要的头信息,如“User-Agent”。
3.自定义拦截器
-
需要实现
InterCeptor
接口public class MyInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); // 创建一个新的 Request,可以在这里修改请求信息,例如添加请求头 Request newRequest = originalRequest.newBuilder() .header("Hello", "A-App") .build(); Response response = chain.proceed(newRequest); return response; } }
-
使用时,在OkHttpClient 中配置这个拦截器。想要添加多个拦截器的话,可以将其添加到拦截器链中。
OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new MyInterceptor()) .addInterceptor(new AnotherInterceptor()) .build();
连接池
1.简介
-
OkHttp 连接池是 OkHttp 客户端的一部分,它负责管理 HTTP 连接的生命周期,以提高网络请求的效率。
-
连接池可以重用现有的连接,避免了频繁地创建和销毁连接,从而减少了延迟并节省了资源。
-
OkHttp 默认使用一个简单的连接池,可以通过配置 OkHttpClient 来调整连接池的行为。
2.常用参数配置选项
- maxIdleConnections(最大连接数):这是连接池中保持空闲的最大连接数。如果连接超过了这个限制,旧连接会被丢弃。
- connectTimeout(连接超时时间):这是建立连接的超时时间,单位是毫秒。
- readTimeout(读取超时时间):这是读取数据的超时时间,单位是毫秒。
- writeTimeout(写入超时时间):这是写入数据的超时时间,单位是毫秒。
- cleanupThreadInterval(清理间隔):这是连接池清理线程运行的时间间隔,默认为 5 分钟。
Dispatcher和线程池
1.简介
- Dispatcher中文是分发器的意思,和拦截器不同的是分发器不做事件处理,只做事件流向。
- 他负责将每一次Requst进行分发,压栈到自己的线程池,并通过调用者自己不同的方式进行异步和同步处理。
- 确保请求被顺序执行,并且控制着同时执行的请求数量,以避免网络拥塞和资源耗尽。
- Dispatcher与一个线程池一起工作,这个线程池由固定数量的线程组成。线程池的大小可以通过OkHttpClient的构造函数进行配置。
2.重要方法
-
RealCall.execute
execute方法同步地发送请求并等待响应, 当调用execute时,当前线程会阻塞,直到收到服务器的响应。
这个方法适用于简单的请求,或者当你需要直接处理响应(例如,作为同步操作)时。将RealCall加入Dispatcher的runningSyncCalls队列。
-
RealCall.enqueue
enqueue方法异步地发送请求,并将响应的回调放入事件队列中,当调用enqueue时,请求会被发送,但当前线程不会阻塞,可以继续执行其他任务。
响应的回调会在事件队列中等待处理,通常会在主线程上执行,确保用户界面可以流畅地响应用户交互。如果当前正在执行的RealCall的数量小于最大并发数,并且该call对应的Host上的call小于同一host上的最大并发数,则将该call加入runningAsyncCalls,并将这个call放到线程池中进行执行,否则加入readyAsyncCall排队等待。
3.DispatCher中的双端队列
-
readyAsyncCalls:准备运行的异步请求
异步的缓存,正在准备被消费的(用数组实现,可自动扩容,无大小限制)。
-
runningAsyncCalls:正在运行的异步请求
正在运行的 异步的任务集合,仅仅是用来引用正在运行的任务以判断并发量,注意它并不是消费者缓存。
-
runningSyncCalls:正在运行的同步请求
正在运行的,同步的任务集合。仅仅是用来引用正在运行的同步任务以判断并发量。
OkHttp 设置了默认的最大并发请求量 maxRequests = 64 和单个 Host 主机支持的最大并发量 maxRequestsPerHost = 5
4.总结
- Dispatcher和线程池在OkHttp中协同工作,确保网络请求被有效、高效地处理。
- Dispatcher负责请求的调度和管理,而线程池负责实际的网络操作和数据传输。
- 这种设计既保证了网络请求的有序执行,又避免了资源的过度消耗。