版本:4.3.1
框架流程
image.png- 创建OkHttpClient对象
- 创建Request对象
- 通过OkHttpClient将Request封装成Call对象
- 通过Call执行请求同步/异步(实际是由Dispatcher进行调度)
- 通过Interceptors处理请求与响应
基本使用
//1.创建OkHttpClient对象
//OkHttpClient client = new OkHttpClient();
//Builder
OkHttpClient client = new OkHttpClient().newBuilder().readTimeout(5, TimeUnit.SECONDS).build();
//2.创建Request对象
Request request = new Request.Builder()
.url(url)
.get()//默认就是GET请求,可以不写
.build();
//3.通过OkHttpClient将Request封装成Call对象
Call call = client.newCall(request);
//4.执行同步请求
Response response = call.execute();
//4.执行异步请求
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("okHttp", "onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("okHttp", "onResponse: " + response.body().string());
}
});
源码分析
- 不管是同步请求还是异步请求,都必须先创建OkHttpClient和Request对象
Dispatcher任务调度器在OkHttpClient.Builder()进行构建
class Builder constructor() {
internal var dispatcher: Dispatcher = Dispatcher()// 调度器
internal var connectionPool: ConnectionPool = ConnectionPool() // 连接池
internal val interceptors: MutableList<Interceptor> = mutableListOf() // 拦截器
internal val networkInterceptors: MutableList<Interceptor> = mutableListOf() // 网络拦截器
internal var eventListenerFactory: EventListener.Factory = EventListener.NONE.asFactory()
internal var retryOnConnectionFailure = true // 重试连接失败
internal var authenticator: Authenticator = Authenticator.NONE // 本地身份验证
internal var followRedirects = true // 本地重定向
internal var followSslRedirects = true // 安全套接层重定向
internal var cookieJar: CookieJar = CookieJar.NO_COOKIES // cookie
internal var cache: Cache? = null // 缓存
internal var dns: Dns = Dns.SYSTEM // 域名
internal var proxy: Proxy? = null // 代理
internal var proxySelector: ProxySelector? = null // 代理选择器
internal var proxyAuthenticator: Authenticator = Authenticator.NONE // 代理身份验证
internal var socketFactory: SocketFactory = SocketFactory.getDefault() // socket 工厂
internal var sslSocketFactoryOrNull: SSLSocketFactory? = null // 安全套接层 socket 工厂,用于 https
internal var x509TrustManagerOrNull: X509TrustManager? = null
internal var connectionSpecs: List<ConnectionSpec> = DEFAULT_CONNECTION_SPECS // 传输层版本和连接协议
internal var protocols: List<Protocol> = DEFAULT_PROTOCOLS // 协议
internal var hostnameVerifier: HostnameVerifier = OkHostnameVerifier // 主机名字验证
internal var certificatePinner: CertificatePinner = CertificatePinner.DEFAULT // 证书链
internal var certificateChainCleaner: CertificateChainCleaner? = null // 验证确认响应证书 适用 HTTPS 请求连接的主机名
Request.Builder()
constructor() {
this.method = "GET"
this.headers = Headers.Builder()
}
不管同步请求还是异步请求,都是调用Call(类RealCall)的方法执行
//同步请求
override fun execute(): Response {
synchronized(this) {
// 每个 call 只能执行一次
check(!executed) { "Already Executed" }
executed = true
}
transmitter.timeoutEnter()
transmitter.callStart()
try {
// 请求开始, 将自己加入到runningSyncCalls队列中
//真正请求的是dispatcher.executed方法
client.dispatcher.executed(this)
// 通过一系列拦截器请求处理和响应处理得到最终的返回结果
return getResponseWithInterceptorChain()
} finally {
//执行完成之后从队列中移除请求
client.dispatcher.finished(this)
}
}
@Throws(IOException::class)
fun getResponseWithInterceptorChain(): Response {
// Build a full stack of interceptors.
// 配置 OkhttpClient 时设置的拦截器
val interceptors = mutableListOf<Interceptor>()
interceptors += client.interceptors
// 负责失败重试以及重定向
interceptors += RetryAndFollowUpInterceptor(client)
// 负责封装 request 和 response
interceptors += BridgeInterceptor(client.cookieJar)
// 缓存相关的拦截器,负责读取缓存直接返回、更新缓存
interceptors += CacheInterceptor(client.cache)
// 负责和服务器建立连接
interceptors += ConnectInterceptor
if (!forWebSocket) {
interceptors += client.networkInterceptors
}
// 负责向服务器发送请求数据、从服务器读取响应数据
interceptors += CallServerInterceptor(forWebSocket)
同步请求调用realCall.executed方法,在该方法中调用dispatcher.executed将realCall添加到同步运行对列中runningSyncCalls然后调用getResponseWithInterceptorChain获取响应报文。
//异步请求
override fun enqueue(responseCallback: Callback) {
synchronized(this) {
check(!executed) { "Already Executed" }
executed = true
}
transmitter.callStart()
//封装成了AsyncCall,它就是一个Runable
client.dispatcher.enqueue(AsyncCall(responseCallback))
}
private fun promoteAndExecute(): Boolean {
this.assertThreadDoesntHoldLock()
val executableCalls = mutableListOf<AsyncCall>()
val isRunning: Boolean
synchronized(this) {
val i = readyAsyncCalls.iterator()
while (i.hasNext()) {
val asyncCall = i.next()
// 正在运行的异步请求超过64
if (runningAsyncCalls.size >= this.maxRequests) break // Max capacity.
// 同一个host下的异步请求超过5个
if (asyncCall.callsPerHost().get() >= this.maxRequestsPerHost) continue // Host max capacity.
i.remove()
asyncCall.callsPerHost().incrementAndGet()
executableCalls.add(asyncCall)
runningAsyncCalls.add(asyncCall)
}
isRunning = runningCallsCount() > 0
}
异步请求的时候,通过dispatcher.enqueue方法将call(封装成了Runable(AsyncCall,它是RealCall的的内部类))添加到就绪对列中,然后循环就绪对列,如果现在执行的任务数没有超过最大的请求数(64)就添加到执行对列中,然后执行asyncCall.executeOn(executorService());。
Dispatcher任务调度
Dispatcher的各个参数的说明如下:
//支持的最大并发请求数量
@get:Synchronized var maxRequests = 64
set(maxRequests) {
require(maxRequests >= 1) { "max < 1: $maxRequests" }
synchronized(this) {
field = maxRequests
}
promoteAndExecute()
}
//每个主机的最大请求数量
@get:Synchronized var maxRequestsPerHost = 5
set(maxRequestsPerHost) {
require(maxRequestsPerHost >= 1) { "max < 1: $maxRequestsPerHost" }
synchronized(this) {
field = maxRequestsPerHost
}
promoteAndExecute()
}
//请求线程池
private var executorServiceOrNull: ExecutorService? = null
//将要运行的异步请求队列
private val readyAsyncCalls = ArrayDeque<AsyncCall>()
//正在运行的异步请求队列
private val runningAsyncCalls = ArrayDeque<AsyncCall>()
//正在运行的同步请求队列
private val runningSyncCalls = ArrayDeque<RealCall>()
-
maxRequests :OkHttp支持的最大并发请求数量
-
maxRequestsPerHost :每个主机的最大请求数量
-
readyAsyncCalls :将要运行的异步请求队列
-
runningAsyncCalls :正在运行的异步请求队列
-
runningSyncCalls :正在运行的同步请求队列
Dispatcher的executorService方法,如下:
@get:Synchronized
@get:JvmName("executorService") val executorService: ExecutorService
get() {
if (executorServiceOrNull == null) {
executorServiceOrNull = ThreadPoolExecutor(0, Int.MAX_VALUE, 60, TimeUnit.SECONDS,
SynchronousQueue(), threadFactory("OkHttp Dispatcher", false))
}
return executorServiceOrNull!!
}
Dispatcher初始化了一个线程池,核心线程的数量为0 ,最大的线程数量为Integer.MAX_VALUE,空闲线程存在的最大时间为60秒。
再来看一遍流程图进行总结
image.png- 同步方法总结
- 创建OkHttpClient和Request对象
- 将Request封装成Call对象
- 调用Call的execute发送同步请求
- 发送请求之后就会进入阻塞状态,直到收到响应
- 异步方法总结
- 创建OkHttpClient和Request对象
- 将Request封装成Call对象
- 调用Call的enqueue进行异步请求
- 发送请求之后就会进入阻塞状态,直到收到响应
- 判断当前call对象,创建一个AsyncCall队列,执行dispatcher的enqueue方法。
okhttp中的拦截器
@Throws(IOException::class)
fun getResponseWithInterceptorChain(): Response {
// Build a full stack of interceptors.
// 配置 OkhttpClient 时设置的拦截器
val interceptors = mutableListOf<Interceptor>()
interceptors += client.interceptors
// 负责失败重试以及重定向
interceptors += RetryAndFollowUpInterceptor(client)
// 负责封装 request 和 response
interceptors += BridgeInterceptor(client.cookieJar)
// 缓存相关的拦截器,负责读取缓存直接返回、更新缓存
interceptors += CacheInterceptor(client.cache)
// 负责和服务器建立连接
interceptors += ConnectInterceptor
if (!forWebSocket) {
interceptors += client.networkInterceptors
}
// 负责向服务器发送请求数据、从服务器读取响应数据
interceptors += CallServerInterceptor(forWebSocket)
-
在配置 OkHttpClient 时设置的 interceptors ()
-
负责失败重试以及重定向的RetryAndFollowUpInterceptor
-
负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转为用户友好的响应的 BridgeInterceptor
-
负责读取缓存直接返回、更新缓存的 CacheInterceptor
-
负责和服务器建立连接的 ConnectInterceptor
-
配置 OkHttpClient 时设置的 networkInterceptors
-
负责向服务器发送请求数据、从服务器读取响应数据的 CallServerInterceptor
-
在 return chain.proceed(originalRequest),中开启链式调用
网友评论