日常-okhttp

1. 背景

 

2. 介绍

2.1 为什么okhttp性能好

  • 支持http2,对一台机器的所有请求共享同一个socket
  • 内置连接池,支持连接复用,减少延迟(连接池复用)
  • 支持透明的gzip压缩响应体(请求头Content-Encoding:gzip,body有内容)
  • 通过缓存避免重复的请求(缓存)
  • 请求失败时自动重试主机的其他ip,自动重定向(重试)

2.2 okhttp工作流程

3. 源码

3.1 socket连接池复用

okhttp3.internal.connection.RealConnectionPool#transmitterAcquirePooledConnection。这是入口okhttp3.internal.connection.Transmitter#newExchange$okhttp

fun transmitterAcquirePooledConnection(
    address: Address,
    transmitter: Transmitter,
    routes: List<Route>?,
    requireMultiplexed: Boolean
  ): Boolean {
    assert(Thread.holdsLock(this))
    for (connection in connections) {
      if (requireMultiplexed && !connection.isMultiplexed) continue
      if (!connection.isEligible(address, routes)) continue
      // 复用连接
      transmitter.acquireConnectionNoEvents(connection)
      return true
    }
    return false
  }

3.2 支持透明的gzip压缩响应体(请求头Content-Encoding:gzip,body有内容)

okhttp源码中执行请求时,会进行synchronized限制(对象锁)。不允许重复请求。

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)
    }
  }

4. 实战

4.1 如何使用OkhttpClient

public static void main(String[] args) throws IOException {
        String url = "http://wwww.baidu.com";
        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .get()//默认就是GET请求,可以不写
                .build();
        Call call = okHttpClient.newCall(request);
        // 异步
//        call.enqueue(new Callback() {
//            @Override
//            public void onFailure(Call call, IOException e) {
//                System.out.println("onFailure");
//            }
//
//            @Override
//            public void onResponse(Call call, Response response) throws IOException {
//                System.out.println("onResponse");
//            }
//        });
        // 同步
        Response execute = call.execute();
        System.out.println(execute);
    }
<dependency>
   <groupId>com.squareup.okhttp3</groupId>
   <artifactId>okhttp</artifactId>
   <version>4.2.2</version>
</dependency>

 

5. FAQ

5.1 弱网

按照移动的特性来说,一般应用低于2G速率的都属于弱网,也可以将3G划分为弱网。除此之外,弱信号的Wifi通常也会被纳入到弱网测试场景中。

5.2 Thread.holdsLock()

检测一个线程是否有对象锁

5.3 同步方法调用时似乎只看到执行前入队,执行后出队

6. 参考资料

OkHttp中的Socket连接

扔掉okhttp、httpClient,来试试这款轻量级HTTP客户端神器?

看完这篇再摸不懂OkHttp,我跪搓衣板

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值