188bet手机版

摘要:后期我会面试50家二线以上的互联网公司,不断总结完善和思考,写出一本完美的安卓面试书籍,大家支持我吗?目录1、okhttp工作的大致流程2、okhttp中的连接池3、参考连接1、okhttp工作的大致流程1.1、整体流程(1)、当我们通过OkhttpClient创立一个Call,并发起同步或者异步请求

后期我会面试50家二线以上的互联网公司,不断总结完善和思考,写出一本完美的安卓面试书籍,大家支持我吗?

目录

1、okhttp工作的大致流程
2、okhttp中的连接池
3、参考连接

1、okhttp工作的大致流程

1.1、整体流程

(1)、当我们通过OkhttpClient创立一个Call,并发起同步或者异步请求时;
(2)、okhttp会通过Dispatcher对我们所有的RealCall(Call的具体实现类)进行统一管理,并通过execute()及enqueue()方法对同步或者异步请求进行解决;
(3)、execute()及enqueue()这两个方法会最终调用RealCall中的getResponseWithInterceptorChain()方法,从阻拦器链中获取返回结果;
(4)、阻拦器链中,依次通过RetryAndFollowUpInterceptor(重定向阻拦器)、BridgeInterceptor(桥接阻拦器)、CacheInterceptor(缓存阻拦器)、ConnectInterceptor(连接阻拦器)、CallServerInterceptor(网络阻拦器)对请求依次解决,与服务的建立连接后,获取返回数据,再经过上述阻拦器依次解决后,最后将结果返回给调用方。
提供两张图便于了解和记忆:


okhttp整体流程1okhttp整体流程2

这张图只画出了请求流程,没有数据返回流程,后期会解决。

1.2、各大阻拦器的原了解析

1.2.1、RetryAndFollowUpInterceptor:负责重定向

构建一个StreamAllocation对象,而后调用下一个阻拦器获取结果,从返回结果中获取重定向的request,假如重定向的request不为空的话,并且不超过重定向最大次数的话就进行重定向,否则返回结果。注意:这里是通过一个while(true)的循环完成下一轮的重定向请求。

(1)、StreamAllocation为什么在第一个阻拦器中就进行创立?
???????便于取消请求以及出错释放资源。
(2)、StreamAllocation的作用是什么?
???????StreamAllocation负责统筹管理Connection、Stream、Call三个实体类,具体就是为一个Call(Realcall),寻觅( findConnection() )一个Connection(RealConnection),获取一个Stream(HttpCode)。

1.2.2、BridgeInterceptor

负责将原始Requset转换给发送给服务端的Request以及将Response转化成对调用方友好的Response,具体就是对request增加Content-Type、Content-Length、Connection、Accept-Encoding等请求头以及对返回结果进行解压等。

1.2.3、CacheInterceptor

CacheInterceptor:负责读取缓存以及升级缓存。
在请求阶段:

  1. 读取候选缓存cacheCandidate;
  2. 根据originOequest和cacheresponse创立缓存策略CacheStrategy;
  3. 根据缓存策略,来决定能否使用网络或者者使用缓存或者者返回错误。
    具体的的缓存策略就是http的缓存策略,详见下图:
    在结果返回阶段:
    负责将网络结果进行缓存(使用于DiskLruCache)。
okhttp&http缓存策略

强制缓存:当用户端第一次请求数据是,服务端返回了缓存的过期时间(Expires与Cache-Control),没有过期即可以继续使用缓存,否则则不适用,无需再向服务端讯问。
比照缓存:当用户端第一次请求数据时,服务端会将缓存标识(Etag/If-None-Match与Last-Modified/If-Modified-Since)与数据一起返回给用户端,用户端将两者都备份到缓存中 ,再次请求数据时,用户端将上次备份的缓存
标识发送给服务端,服务端根据缓存标识进行判断,假如返回304,则表示缓存可用,假如返回200,标识缓存不可用,使用188bet下载返回的数据。

ETag是用资源标识码标识资源能否被修改,Last-Modified是用时间戳标识资源能否被修改。ETag优先级高于Last-Modified。

1.2.4、ConnectInterceptor:负责与服务器建立连接

使用StreamAllocation.newStream来和服务端建立连接,并返回输入输出流(HttpCodec),实际上是通过StreamAllocation中的findConnection寻觅一个可用的Connection,而后调用Connection的connect方法,使用socket与服务端建立连接。

1.2.5、CallServerInterceptor:负责从服务器读取响应的数据

主要的工作就是把请求的Request写入到服务端,而后从服务端读取Response。
(1)、写入请求头
(2)、写入请求体
(3)、读取响应头
(4)、读取响应体

2、连接池原理

因为HTTP是基于TCP,TCP连接时需要经过三次握手,为了加快网络访问速度,我们可以Reuqst的header中将Connection设置为keepalive来复用连接。

Okhttp支持5个并发KeepAlive,默认链路生命为5分钟(链路空闲后,保持存活的时间),连接池有ConectionPool实现,对连接进行回收和管理。

2.1、连接池的清除

连接池清除1

在ConectionPool中有一个异步线程去清除连接池中的连接,首先通过cleanup方法执行清除,而后等待clean返回的时间后,再次进行清除,以此循环,持续清除。

连接池原理2

1、首先空闲连接数量;
2、而后通过for循环查找最长空闲时间的连接以及对应空闲时长;
3、而后判断这个最长空闲时间的连接能否超出最大空闲连接数或者者或者者超过最大空闲时间,满足其一则清理最长空闲的连接。假如不满足清除条件,则返回一个对应等待时间。
这个对应等待的时间又分二种情况:
1 有空闲连接:则返回:keepAliveDurationNs-longestIdleDurationNs;
2 没有空闲的连接,则返回:keepAliveDurationNs
注意:清理一个空闲连接后,会返回0,再次立即开始清除。

如何空闲连接呢?


空闲连接

StreamAllocation创立一个Connection后会将自己增加到Connection的connection.allocations列表中,数据读取完毕之后,会将自己从Connection的connection.allocations中移除,所以判读一个Connection能否是空闲连接可以采用引用计数法,判断connection.allocations列表中能否有StreamAllocation,假如没有就是空闲连接,否则不是。

3、参考链接

由于本文是极度针对面试的,所以未解释过多名词和粘贴过多代码,假如不明白其中原理,可以参考下面两篇链接:
3.1、https://www.jianshu.com/p/6166d28983a2
3.2、https://juejin.im/post/5a704ed05188255a8817f4c9#heading-15

  • 全部评论(0)
188bet下载发布的资讯信息
【系统环境|】你是HTML 5的一员吗?(2019-08-15 11:58)
【系统环境|】Web前端基础怎么学?html、css、JavaScript 知识架构图(2019-08-14 17:55)
【系统环境|】零基础小白走Web前端之路是否可行?答案是yes!(2019-08-13 11:44)
【系统环境|】你知道Web前端与HTML5技术的区别吗?(2019-08-12 14:10)
【系统环境|】移动前端开发和web前端开发的区别(2019-08-11 16:49)
【系统环境|】给新手的锦囊:Web前端开发小白的学习建议和路线图(2019-08-10 16:34)
【系统环境|】都说web前端开发薪资高,入行就有上万月薪,转行难吗?(2019-08-09 14:55)
【系统环境|】干货教程 | Web前端开发学习入门指南(2019-08-08 18:27)
【系统环境|】前端开发:vue路由之前端路由的原理(2019-08-07 13:17)
【系统环境|】你不知道的web前端那些事(2019-08-06 12:29)
188bet手机版二维码188bet手机版访问领取大礼包
返回顶部