欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > OkHttp

OkHttp

2024/10/25 14:35:09 来源:https://blog.csdn.net/ysqyes/article/details/142748621  浏览:    关键词:OkHttp

OkHttp是一个用于Android和Java应用的高效HTTP客户端库。它具有以下优点:

优点

  1. 高效连接池
    • 支持连接复用(Connection Pooling)减少延迟。
    • 有效管理HTTP/2多路复用。
  2. 透明压缩
    • 自动处理Gzip压缩,减少传输的数据量。
  3. 缓存响应
    • 内置缓存机制,帮助减少不必要的网络调用,提高速度和节省流量。
  4. 异步请求
    • 支持异步请求,避免阻塞主线程,提高应用响应速度。
  5. 支持WebSocket
    • 提供WebSocket支持,便于实时通信。
  6. 安全性
    • 支持TLS加密,确保数据传输的安全性。
  7. 易于集成和使用
    • 简单的API设计,方便与其他库(如Retrofit)集成。

简单使用

  1. 依赖
    implementation("com.squareup.okhttp3:okhttp:4.9.3")implementation("com.google.code.gson:gson:2.8.8")
  1. 定义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
)
  1. 直接调用即可,主要在接收到后使用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(传输层)
  1. Deque(双端队列)
    等待队列
    private val readyAsyncCalls = ArrayDeque()
    异步队列
    private val runningAsyncCalls = ArrayDeque()
    同步队列
    private val runningSyncCalls = ArrayDeque()
  2. 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()}
  1. 基于第二点的控制,所以线程池不设置等待队列,使用SynchronousQueue无容量队列,且最大线程数无限,核心为0
        executorServiceOrNull = ThreadPoolExecutor(0, Int.MAX_VALUE, 60, TimeUnit.SECONDS,SynchronousQueue(), threadFactory("$okHttpName Dispatcher", false))
  1. 执行结束后移除队列,并执行回调
  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()}}
  1. 构建者模式,责任链模式
  2. connectInteceptor创建socket请求
  3. ConnectionPool,设置线程池为守护线程
    • 避免阻止 JVM 正常退出。
    • 更高效地管理后台任务和连接。
    • 自动清理资源,防止资源泄漏。
  4. promoteCalls执行下一个任务

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com