OkHttp 源码分析
集成
采用[Gradle][https://gradle.org]构建方式集成最新版本的[OkHttp][https://github.com/square/okhttp]
dependencies {
implementation "com.squareup.okhttp3:okhttp:4.9.0"
}
使用
初始化
// 初始化客户端
val httpClient:OkHttpClient = OkHttpClient.Builder()
.callTimeout(Duration.ofMillis(TIMEOUT_CALL))
.connectTimeout(Duration.ofMillis(TIMEOUT_CONNECT))
.readTimeout(Duration.ofMillis(TIMEOUT_READ))
.writeTimeout(Duration.ofMillis(TIMEOUT_WRITE))
.build()
// 实例化请求体
val request = Request.Builder()
.url("https://github.com/api")
.header("Content-Type","application/json")
.build()
// 实例化Call
val call =httpClient.newCall(request)
如果使用同步请求
val resposne = call.execute()
resposne?.let {
response ->
TODO("Do something")
}
如果使用异步请求
// 如果使用异步请求
call.enqueue(object :Callback{
override fun onFailure(call: Call, e: IOException) {
TODO("Not yet implemented")
}
override fun onResponse(call: Call, response: Response) {
TODO("Not yet implemented")
}
})
相关类
OkHttpClient
open class OkHttpClient internal constructor(
builder: Builder
) : Cloneable, Call.Factory, WebSocket.Factory {
// 异步任务管理类,内部有一个线程池
val dispatch:Dispatch;
// http连接池,用于连接复用
val connectionPool:ConectionPool;
// 应用拦截器与网络拦截器
val interceptors:List<Interceptor>;
val networkInterceptors:List<Interceptor>;
// 参数
val connectTimeoutMillis:Int;
val readTimeoutMillis:Int;
val writeTimeoutMillis:Int;
// 其他
}
OkHttpClient
类中看到的dispatch
用于异步任务的管理,实现了线程池的复用,而connectionPool
则实现了Http
连接池的复用,这两个资源的合理配置实现了OkHttp高并发,低消耗
的特点。
同时,OkHttpClient
实现了Call
工厂方法的接口Call.Factory
fun interface Factory {
fun newCall(request: Request): Call
}
通过newCall
可以得到RealCall
对象。后文中查看Call
接口类,发现该类实现了Cloneable
接口,以为其内部会用到对象池技术,结果从OkHttpClient
的实现来看,并未使用此技术。
override fun newCall(request: Request): Call = RealCall(this, request, forWebSocket = false)
Request
Request
是对请求体的抽象。
class Request internal constructor(
@get:JvmName("url") val url: HttpUrl,
@get:JvmName("method") val method: String,
@get:JvmName("headers") val headers: Headers,
@get:JvmName("body") val body: RequestBody?,
internal val tags: Map<Class<*>, Any>
) {
}
备注
method
字段实现了GET
、POST
、HEAD
、PUT
、PATCH
、DELETE
- 如果
body
字段为空,或者本身是可变的,则request
对象是可变的
Response
Response
是对响应体的抽象
class Response internal constructor(
val request:Request,
val message:String,
val code:Int,
val headers:Headers,
val body:ResponseBody,
..