What?
OkHttp 是一个高效的 HTTP 客户端
它的前世今生,square在使用Android底层HTTP的API不是很好用,内部团队就封装了一套网络请求库命名OkHttp,随着多次迭代修改,摒弃了Apache HttpClient,完全使用HttpURLConnection,Android 6.0,API23.6以后google官方剔除了HttpClient,使用OKHTTP封装的源码。
Why?
正式由于它的强大与优秀,所以被google官方收购使用
优点:
1.HTTP / 2支持允许对同一主机的所有请求共享套接字。
2.连接池减少了请求延迟(如果HTTP / 2不可用)。
3.透明GZIP缩小了下载大小。
4.响应缓存可以完全避免网络重复请求。
5.支持https,http,socket
How?
OkHttpClient okHttpClient =new OkHttpClient();
final Request request =new Request.Builder().url("https://www.baidu.com").build();
okhttp3.Call call =okHttpClient.newCall(request);
call.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(@NotNull okhttp3.Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull okhttp3.Call call, @NotNull okhttp3.Response response) throws IOException {
Log.i("okhttp",response.message());
}
});
Code?
1.实例化OkHttpClient两种方式,Builder模式和new,builder设置参数缓存,拦截器,时间等。
OkHttpClient okHttpClient =new OkHttpClient();
okHttpClient.newBuilder().readTimeout(Duration.ofMillis(1000)).cache(null).addInterceptor(null);
2.Builder实例化请求Request ,设置请求请求参数,url,请求头等。
final Request request =new Request.Builder().url("https://www.baidu.com").build();
3.实现Call设置请求请求参数,url,请求头等。
okhttp3.Call call =okHttpClient.newCall(request);
/** Prepares the [request] to be executed at some point in the future. */
override fun newCall(request: Request): Call {
return RealCall.newRealCall(this, request, forWebSocket = false)
}
4.异步和同步请求回调调用
call.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(@NotNull okhttp3.Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull okhttp3.Call call, @NotNull okhttp3.Response response) throws IOException {
Log.i("okhttp",response.message());
}
});
流程图

1.OkHttpClient
//缓存
public final val cache: okhttp3.Cache? /* compiled code */
//默认呼叫超时(以毫秒为单位)。默认情况下,完成调用没有超时,但是在调用中有连接,写入和读取操作。
public final val callTimeoutMillis: kotlin.Int /* compiled code */
//证书序列
public final val certificateChainCleaner: okhttp3.internal.tls.CertificateChainCleaner? /* compiled code */
//用来自签名证书管理
public final val certificatePinner: okhttp3.CertificatePinner /* compiled code */
//连接超时事件
public final val connectTimeoutMillis: kotlin.Int /* compiled code */
//连接池
public final val connectionPool: okhttp3.ConnectionPool /* compiled code */
//连接规格
public final val connectionSpecs: kotlin.collections.List<okhttp3.ConnectionSpec> /* compiled code */
//cookie存储器
public final val cookieJar: okhttp3.CookieJar /* compiled code */
//线程调度器
public final val dispatcher: okhttp3.Dispatcher /* compiled code */
//Dns设置
public final val dns: okhttp3.Dns /* compiled code */
//生产统计事件
public final val eventListenerFactory: okhttp3.EventListener.Factory /* compiled code */
//设置是否跳转
public final val followRedirects: kotlin.Boolean /* compiled code */
//当你访问http是否跳转https
public final val followSslRedirects: kotlin.Boolean /* compiled code */
//host验证器
public final val hostnameVerifier: javax.net.ssl.HostnameVerifier /* compiled code */
//拦截器
public final val interceptors: kotlin.collections.List<okhttp3.Interceptor> /* compiled code */
//返回观察单个网络请求和响应的不可变拦截器列表,这些拦截器必须只调用一次
public final val networkInterceptors: kotlin.collections.List<okhttp3.Interceptor> /* compiled code */
//长连接心跳发送时间
public final val pingIntervalMillis: kotlin.Int /* compiled code */
//支持http的协议版本
public final val protocols: kotlin.collections.List<okhttp3.Protocol> /* compiled code */
//代理服务器
public final val proxy: java.net.Proxy? /* compiled code */
//代理授权设置
public final val proxyAuthenticator: okhttp3.Authenticator /* compiled code */
//授权设置
public final val authenticator: okhttp3.Authenticator /* compiled code */
//读取超时事件
public final val readTimeoutMillis: kotlin.Int /* compiled code */
//连接失败,是否重试
public final val retryOnConnectionFailure: kotlin.Boolean /* compiled code */
//生产Socket
public final val socketFactory: javax.net.SocketFactory /* compiled code */
//生产sslSocket
public final val sslSocketFactory: javax.net.ssl.SSLSocketFactory /* compiled code */
//写入超时时间
public final val writeTimeoutMillis: kotlin.Int /* compiled code */
//证书设置
public final val x509TrustManager: javax.net.ssl.X509TrustManager? /* compiled code */
2.Request请求方法体
internal constructor(request: Request) {
this.url = request.url
this.method = request.method
this.body = request.body
this.tags = if (request.tags.isEmpty()) {
mutableMapOf()
} else {
request.tags.toMutableMap()
}
this.headers = request.headers.newBuilder()
}
3.RealCall
//同步请求
override fun execute(): Response {
synchronized(this) {
check(!executed) { "Already Executed" }
executed = true
}
transmitter.timeoutEnter()
transmitter.callStart()
try {
client.dispatcher.executed(this)
return getResponseWithInterceptorChain()
} finally {
client.dispatcher.finished(this)
}
}
//异步请求
override fun enqueue(responseCallback: Callback) {
synchronized(this) {
check(!executed) { "Already Executed" }
executed = true
}
transmitter.callStart()
client.dispatcher.enqueue(AsyncCall(responseCallback))
}
//取消
override fun cancel() {
transmitter.cancel()
}
//异步请求内部方法体
internal inner class AsyncCall(
private val responseCallback: Callback
) : Runnable {
override fun run() {
threadName("OkHttp ${redactedUrl()}") {
var signalledCallback = false
transmitter.timeoutEnter()
try {
val response = getResponseWithInterceptorChain()
signalledCallback = true
responseCallback.onResponse(this@RealCall, response)
} catch (e: IOException) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for ${toLoggableString()}", e)
} else {
responseCallback.onFailure(this@RealCall, e)
}
} finally {
client.dispatcher.finished(this)
}
}
}
}
@Throws(IOException::class)
fun getResponseWithInterceptorChain(): Response {
// Build a full stack of interceptors.
val interceptors = mutableListOf<Interceptor>()
interceptors += client.interceptors
interceptors += RetryAndFollowUpInterceptor(client)
interceptors += BridgeInterceptor(client.cookieJar)
interceptors += CacheInterceptor(client.cache)
interceptors += ConnectInterceptor
if (!forWebSocket) {
interceptors += client.networkInterceptors
}
interceptors += CallServerInterceptor(forWebSocket)
val chain = RealInterceptorChain(interceptors, transmitter, null, 0, originalRequest, this,
client.connectTimeoutMillis, client.readTimeoutMillis, client.writeTimeoutMillis)
var calledNoMoreExchanges = false
try {
val response = chain.proceed(originalRequest)
if (transmitter.isCanceled) {
response.closeQuietly()
throw IOException("Canceled")
}
return response
} catch (e: IOException) {
calledNoMoreExchanges = true
throw transmitter.noMoreExchanges(e) as Throwable
} finally {
if (!calledNoMoreExchanges) {
transmitter.noMoreExchanges(null)
}
}
}
重点!重点!重点!
okhttp核心,采用拦截器成一个任务链,采用责任链模式进行功能解耦,每个interceptor主要任务,事前准备,交给下一个interceptor,事后返回处理,下面看看每个拦截器的任务!
@Throws(IOException::class)
fun getResponseWithInterceptorChain(): Response {
// Build a full stack of interceptors.
val interceptors = mutableListOf<Interceptor>()
interceptors += client.interceptors
interceptors += RetryAndFollowUpInterceptor(client)
interceptors += BridgeInterceptor(client.cookieJar)
interceptors += CacheInterceptor(client.cache)
interceptors += ConnectInterceptor
if (!forWebSocket) {
interceptors += client.networkInterceptors
}
interceptors += CallServerInterceptor(forWebSocket)
val chain = RealInterceptorChain(interceptors, transmitter, null, 0, originalRequest, this,
client.connectTimeoutMillis, client.readTimeoutMillis, client.writeTimeoutMillis)
var calledNoMoreExchanges = false
try {
val response = chain.proceed(originalRequest)
if (transmitter.isCanceled) {
response.closeQuietly()
throw IOException("Canceled")
}
return response
} catch (e: IOException) {
calledNoMoreExchanges = true
throw transmitter.noMoreExchanges(e) as Throwable
} finally {
if (!calledNoMoreExchanges) {
transmitter.noMoreExchanges(null)
}
}
}
网友评论