okhttp3宏观介绍及基础回顾

一、简介

1.1 okhttp是什么?

   okhttp是由美国square [square是什么] 公司开发的,用于安卓和java应用程序的 HTTP+HTTP/2的客户端。

1.2 最新的版本

   目前最新版本为 okhttp3,可以从这个链接获取最新版本的okhttp3的版本号及maven构件地址: https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
   gradle最新版本: compile group: ‘com.squareup.okhttp3’, name: ‘okhttp’, version: ‘4.7.2’

   这里需要注意的是okhttp从大的版本上来说分为两个版本,即okhttp和okhttp3。okhttp可以认是第一个大版本,但从2016年开始就不再维护了;可能有人会有疑问为什么没有okhttp2这个大版本,我猜可能是因为内部团队存在多个优化版本,导致无法统一,因此没有对外发布okhttp2,直接进入了okhttp3。
   在mvnreponsitory仓库中okhttp3的第一个版本为2016年1月发布的3.0.0版本,一直由square维护至今,到本博客的撰写时间,okhttp3的最新版本为 4.7.2版本,发布日期为2020年5月。

1.3 okhttp的优点
   1.3.1 官方宣传的优点

   官方自称的优点[okhttp的github官方宣传] ,翻译过来的意思大概是说:

   okhttp是现代化应用程序的网络通信的方式。它用来帮助程序交换数据和媒体信息,使用okhttp可以让你的程序加载物料(翻译为服务器数据更合适在)更加高效、更节省网络带宽。

   okhttp通过以下措施让你的网络更加高效
1. HTTP/2支持对同一个host的所有网络请求 共享socket。
2. 在不启用HTTP/2的情况,连接池能减少潜在的网络请求。
3. 透明GZIP技术压缩了下载数据的大小。
4. 结果缓存技术避免重复的网络请求。

   OkHttp在网络出现问题时,仍然能支持良好的运行。它能解决常见的网络连接问题。如果你的服务端有多个ip地址,okhttp会在第一个地址连接失败时,自动尝试备用地址。 这种技术在你的服务器有多地备份时,是必须要用到的。OkHttp支持现代TLS特性(TLS 1.3、ALPN、证书固定)。可以将其配置为回滚以实现广播连接。

1.3.2 用户总结的优点-(版本一)
  • 支持HTTP2/SPDY(SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。)
  • socket自动选择最好路线,并支持自动重连,拥有自动维护的socket连接池,减少握手次数,减少了请求延迟,共享Socket,减少对服务器的请求次数。
  • 基于Headers的缓存策略减少重复的网络请求。
  • 拥有Interceptors轻松处理请求与响应(自动处理GZip压缩)。
1.3.3 用户总结的优点-(版本二)
  • 支持HTTP2/SPDY(SPDY是Google开发的基于TCP的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。)
  • socket自动选择最好路线,并支持自动重连,拥有自动维护的socket连接池,减少握手次数,减少了请求延迟,共享Socket,减少对服务器的请求次数。
  • 基于Headers的缓存策略减少重复的网络请求。
  • 拥有Interceptors轻松处理请求与响应(自动处理GZip压缩)。
1.4 okhttp的应用
  1. 用于替代HttpUrlConnection和Apache HttpClient
  2. Android4.4开始,google已经开始将源码中的HttpURLConnection替换为OkHttp
  3. Android6.0里已移除HttpClient
1.5 okhttp的依赖关系

从下图可以看出:

  1. okhttp默认是依赖okio的。
  2. okhttp3: 4.7.2完全使用的是 kotlin编写的
okhttp的依赖关系图okhttp3-4.7.2.jar包
在这里插入图片描123在这里插入图片描述

二、基本使用

     应用okhttp时,主要会关注几个方面的问题,请求的方法类型、同步异步、上传文件、下载文件、上传文件同时携带参数。

2.1 异步get请求

在这里插入图片描述

2.2 异步post请求

在这里插入图片描述

2.3 同步get请求

在这里插入图片描述

2.4 同步post请求

在这里插入图片描述

2.5 get下载文件

在这里插入图片描述

2.6 post上传文件

上传任何文件都需要设置文件类型的MIME,例如上传一个纯文本文件,就需要MediaType.parse(“text/plain; charset=utf-8”)

举例说明MIME值域
在这里插入图片描述在这里插入图片描述
2.7 异步上传Multipart文件,同时携带额外参数
  • 应用场景举例:
       我们在有些情况下既要上传文件还要上传其他类型字段。比如在个人中心我们可以修改名字,年龄,修改图像,这其实就是一个表单。这里我们用到MuiltipartBody ,它 是RequestBody 的一个子类,我们提交表单就是利用这个类来构建一个 RequestBody。
    在这里插入图片描述

三、不常用的功能

3.1 设置超时和缓存

在这里插入图片描述

3.1.1 超时的解释:
  • callTimeout = 0 : 请求超时时长,默认为0,0表示不限制。

    1. Sets the default timeout for complete calls. A value of 0 means no timeout.
    2. The call timeout spans the entire call: resolving DNS, connecting, writing the request body,
      server processing, and reading the response body. If the call requires redirects or retries
      all must complete within one timeout period.
      解读:callTimeout指整个请求生命周期的所有时间,包含dns解析、发起socket连接、写入请求数据、等待服务器处理、读取服务器返回的数据, 通常不需要设置。 这也解释了为什么我们在项目设置的请求超时时间都是10秒,但实在开发过程中总会碰到超过10秒的情况。这是因为对10秒的理解不够深刻。
  • connectTimeout = 10_000

    1. Sets the default connect timeout for new connections. A value of 0 means no timeout,
    2. The connect timeout is applied when connecting a TCP socket to the target host. The default
      value is 10 seconds.
  • writeTimeout = 10_000

    1. Sets the default write timeout for new connections. A value of 0 means no timeout
    2. The write timeout is applied for individual write IO operations. The default value is 10 seconds.
  • readTimeout = 10_000

    1. Sets the default read timeout for new connections. A value of 0 means no timeout
    2. The read timeout is applied to both the TCP socket and for individual read IO operations including on [Source] of the [Response]. The default value is 10 seconds.
3.2 设置请求头

  HTTP 头的数据结构是 Map<String, List>类型。也就是说,对于每个 HTTP 头,可能有多个值。但是大部分 HTTP 头都只有一个值,只有少部分 HTTP 头允许多个值。至于name的取值说明,可以查看这个 HTTP响应头和请求头信息对照表
在这里插入图片描述

3.3 取消请求
  • 场景:

  某些特殊的场景下需要取消网络请求,比如下载文件时用户点击了暂停或取消按钮、某Activity正在请求数据时用户finish关闭掉了当前页面,这些场景下就必须取消请求,以减小资源消耗(如内存、网络、cpu等)。

  • 解决方法:

  OkHttp提供了cancel方法,但是实际在使用过程中发现,如果调用cancel()方法,会回调到CallBack里面的 onFailure方法中。测试发现不同的失败类型返回的IOException e 不一样,所以可以通过e.toString 中的关键字来区分不同的错误类型。

自己主动取消的错误的 java.net.SocketException: Socket closed
超时的错误是 java.net.SocketTimeoutException
网络出错的错误是java.net.ConnectException: Failed to connect to xxxxx

  针对这个问题,可以封装callback的onFailure方法,过滤掉主动取消的状况,以免在不必要的场景下,弹出错误toast提示
在这里插入图片描述

  • 取消单个请求:

  可以通过 call.cancel(); 来取消单个网络请求。
   okhttp源码中对cancel()方法的说明:如果可能的话,将会取消请求。如果请求已经完成,那么将不会被取消。 这意味着,未发出的请求、及正进行中的请求都将会被及时取消。 至少源码是如何实现取消正在进行中的请求,后面源码解读时再具体分析。
在这里插入图片描述
取消请求的例子:
在这里插入图片描述

  • 取消全部请求:

    okhttpclient.dispatcher().cancelAll();

3.4 配置线程池
  1. 为 okhttpClient 创建一个 dispatcher,dispatcher 指定一个 自定义的 ExecutorService。通常可以用于为okhttp的线程指定一个线程名称,便于排查问题
    在这里插入图片描述
  2. 通过查看dispatcher源码可以得知, 默认的dispatcher 也是创建一个ExecutorService。
       - 该线程池与Android下的 Executors.newCachedThreadPool() 比较类似;
       - 无任务上限,自动回收闲置60s的线程,适用于大量耗时较短的任务;
       - 虽然线程池无任务上限,但是Dispatcher对入口enqueue()进行了把关,最大的异步任务数默认是64,同一个主机默认是5,当然这两个默认值是可以修改的,Dispatcher提供的修改接口;

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值