OkHttp是一个用于Android和Java应用的高效HTTP客户端库。它具有以下优点:
优点
- 高效连接池:
- 支持连接复用(Connection Pooling)减少延迟。
- 有效管理HTTP/2多路复用。
- 透明压缩:
- 自动处理Gzip压缩,减少传输的数据量。
- 缓存响应:
- 内置缓存机制,帮助减少不必要的网络调用,提高速度和节省流量。
- 异步请求:
- 支持异步请求,避免阻塞主线程,提高应用响应速度。
- 支持WebSocket:
- 提供WebSocket支持,便于实时通信。
- 安全性:
- 支持TLS加密,确保数据传输的安全性。
- 易于集成和使用:
- 简单的API设计,方便与其他库(如Retrofit)集成。
简单使用
- 依赖
implementation("com.squareup.okhttp3:okhttp:4.9.3")implementation("com.google.code.gson:gson:2.8.8")
- 定义json转换的对象
data class ImageData(val createTime: Long,val id: Long,val name: String,val path: String,val size: Long
)data class ApiResponse(val data: List<ImageData>,val errorCode: Int,val isSuccess: Boolean
)
- 直接调用即可,主要在接收到后使用Gson反序列化。
class OkHttpActivity : AppCompatActivity() {private lateinit var binding: ActivityOkHttpBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityOkHttpBinding.inflate(layoutInflater)setContentView(binding.root)binding.recyclerView.layoutManager = LinearLayoutManager(this)fetchData()}private fun fetchData() {val client = OkHttpClient()val request = Request.Builder().url("http://192.168.42.7:9876/image/listImage?page=0&pageSize=100").build()client.newCall(request).enqueue(object : okhttp3.Callback {override fun onFailure(call: okhttp3.Call, e: IOException) {e.printStackTrace()}override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {response.body?.string()?.let { jsonString ->val apiResponse = Gson().fromJson(jsonString, ApiResponse::class.java)runOnUiThread {binding.recyclerView.adapter = ImageAdapter(apiResponse.data)}}}})}
}
效果
原理
okhttp(传输层)
- Deque(双端队列)
等待队列
private val readyAsyncCalls = ArrayDeque()
异步队列
private val runningAsyncCalls = ArrayDeque()
同步队列
private val runningSyncCalls = ArrayDeque() running队列数量<64,并且同时访问同一个host数量<5,就直接加入running队列,否则则加入等待队列
4.9.3版本:直接加入readyAsyncCalls队列,call.callsPerHost指向同一个AtomicInteger,原子计数。
maxRequests = 64,maxRequestsPerHost = 5在取出时考虑
internal fun enqueue(call: AsyncCall) {synchronized(this) {readyAsyncCalls.add(call)if (!call.call.forWebSocket) {val existingCall = findExistingCallWithHost(call.host)if (existingCall != null) call.reuseCallsPerHostFrom(existingCall)//PerHostFrom原子计数}}promoteAndExecute()}
- 基于第二点的控制,所以线程池不设置等待队列,使用SynchronousQueue无容量队列,且最大线程数无限,核心为0
executorServiceOrNull = ThreadPoolExecutor(0, Int.MAX_VALUE, 60, TimeUnit.SECONDS,SynchronousQueue(), threadFactory("$okHttpName Dispatcher", false))
- 执行结束后移除队列,并执行回调
private fun <T> finished(calls: Deque<T>, call: T) {val idleCallback: Runnable?synchronized(this) {if (!calls.remove(call)) throw AssertionError("Call wasn't in-flight!")idleCallback = this.idleCallback}val isRunning = promoteAndExecute()if (!isRunning && idleCallback != null) {idleCallback.run()}}
- 构建者模式,责任链模式
- connectInteceptor创建socket请求
- ConnectionPool,设置线程池为守护线程
- 避免阻止 JVM 正常退出。
- 更高效地管理后台任务和连接。
- 自动清理资源,防止资源泄漏。
- promoteCalls执行下一个任务