一、okhttp工做的大体流程

1.一、总体流程

(1)、当咱们经过OkhttpClient创立一个Call,并发起同步或者异步请求时;

(2)、okhttp会经过Dispatcher对咱们全部的RealCall(Call的具体实现类)进行统一管理,并经过execute()及enqueue()方法对同步或者异步请求进行解决;

(3)、execute()及enqueue()这两个方法会最终调用RealCall中的getResponseWithInterceptorChain()方法,从阻拦器链中获取返回结果;

(4)、阻拦器链中,依次经过RetryAndFollowUpInterceptor(重定向阻拦器)、BridgeInterceptor(桥接阻拦器)、CacheInterceptor(缓存阻拦器)、ConnectInterceptor(链接阻拦器)、CallServerInterceptor(网络阻拦器)对请求依次解决,与服务的创建链接后,获取返回数据,再通过上述阻拦器依次解决后,最后将结果返回给调用方。

提供两张图便于了解和记忆:缓存

okhttp总体流程1:

服务器

okhttp总体流程2:网络

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

1.二、各大阻拦器的原了解析

1.2.一、RetryAndFollowUpInterceptor:负责重定向异步

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

(1)、StreamAllocation为何在第一个阻拦器中就进行创立?

便于取消请求以及出错释放资源。

(2)、StreamAllocation的做用是什么?

StreamAllocation负责统筹管理Connection、Stream、Call三个实体类,具体就是为一个Call(Realcall),寻觅( findConnection() )一个Connection(RealConnection),获取一个Stream(HttpCode)。spa

1.2.二、BridgeInterceptor线程

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

1.2.三、CacheInterceptorblog

CacheInterceptor:负责读取缓存以及升级缓存。

在请求阶段:

读取候选缓存cacheCandidate;

根据originOequest和cacheresponse创立缓存策略CacheStrategy;

根据缓存策略,来决定可否使用网络或者者使用缓存或者者返回错误。

具体的的缓存策略就是http的缓存策略,详见下图:

在结果返回阶段:

负责将网络结果进行缓存(使用于DiskLruCache)。

okhttp&http缓存策略:

强制缓存:当用户端第一次请求数据是,服务端返回了缓存的过时时间(Expires与Cache-Control),没有过时便可以继续使用缓存,不然则不适用,无需再向服务端讯问。

比照缓存:当用户端第一次请求数据时,服务端会将缓存标识(Etag/If-None-Match与Last-Modified/If-Modified-Since)与数据一块儿返回给用户端,用户端将二者都备份到缓存中 ,再次请求数据时,用户端将上次备份的缓存

标识发送给服务端,服务端根据缓存标识进行判断,假如返回304,则表示缓存可用,假如返回200,标识缓存不可用,使用最新返回的数据。

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

1.2.四、ConnectInterceptor:负责与服务器创建链接

使用StreamAllocation.newStream来和服务端创建链接,并返回输入输出流(HttpCodec),其实是经过StreamAllocation中的findConnection寻觅一个可用的Connection,然后调用Connection的connect方法,使用socket与服务端创建链接。

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

主要的工做就是把请求的Request写入到服务端,然后从服务端读取Response。

(1)、写入请求头

(2)、写入请求体

(3)、读取响应头

(4)、读取响应体

二、链接池原理

由于HTTP是基于TCP,TCP链接时须要通过三次握手,为了加快网络访问速度,咱们能够Reuqst的header中将Connection设置为keepalive来复用链接。

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

2.一、链接池的清除

链接池清除1:

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

链接池原理2:

一、首先统计空闲链接数量;

二、然后经过for循环查找最长空闲时间的链接以及对应空闲时长;

三、然后判断这个最长空闲时间的链接可否超出最大空闲链接数或者者或者者超过最大空闲时间,知足其一则清理最长空闲的链接。假如不知足清除条件,则返回一个对应等待时间。

这个对应等待的时间又分二种状况:

1 有空闲链接:则返回:keepAliveDurationNs-longestIdleDurationNs;

2 没有空闲的链接,则返回:keepAliveDurationNs

注意:清理一个空闲链接后,会返回0,再次当即开始清除。

如何统计空闲链接呢?

统计空闲链接:

StreamAllocation创立一个Connection后会将本身增长到Connection的connection.allocations列表中,数据读取完毕以后,会将本身从Connection的connection.allocations中移除,因此判读一个Connection可否是空闲链接能够采用引用计数法,判断connection.allocations列表中可否有StreamAllocation,假如没有就是空闲链接,不然不是。

粉丝技术交流会:

android中okhttp原理详解,Android中okhttp原理详解-极度针对面试篇相关推荐

  1. okhttp post php,Android_详解Android中使用OkHttp发送HTTP的post请求的方法,HTTP POST 和 PUT 请求可以包含要 - phpStudy...

    详解Android中使用OkHttp发送HTTP的post请求的方法 HTTP POST 和 PUT 请求可以包含要提交的内容.只需要在创建 Request 对象时,通过 post 和 put 方法来 ...

  2. Android中View(视图)绘制不同状态背景图片原理深入分析以及StateListDrawable使用详解...

    2019独角兽企业重金招聘Python工程师标准>>> 今天继续给大家分享下View的相关知识,重点有一下两点:   1.View的几种不同状态属性            2.如何根 ...

  3. android 清空数组缓存,Android数据持久化之读写SD卡中内容的方法详解

    本文实例讲述了Android数据持久化之读写SD卡中内容的方法.分享给大家供大家参考,具体如下: 前面文章里讲的那三个方法:openFileOutput.openFileInput虽然都能通过流对象O ...

  4. android中接口的作用是什么意思,详解Android接口Interface的使用和意义

    本文介绍是Android的一个重要的东西,接口Interface,详解两个方面: (1)Java是继承的,接口Interface是可以多个的,恰恰弥补了这个缺点. (2)回调,接口Interface里 ...

  5. android中的TextView组件,Android-TextView文本视图控件详解

    TextView是Android开发当中运用到最多的控件之一,显示一行或者多行文本,也可以给上下左右设置图片,并且结合SpannableString和其子类可以做到图文混排. TextView文本视图 ...

  6. 在android中执行多个动画,Android上几种Animation和多个动画同时播放以ScaleAnimation应用详解...

    在API Demo的View->Animation下可以找到四个Animation的Demo,第一个3D Translate比较复杂,最后再讲,先讲第2个Interpolator.该Activi ...

  7. android:stretchcolumns=quot;*quot;,详解Android TableLayout中stretchColumns、shrinkColumns的用法...

    详解Android 中TableLayout中stretchColumns.shrinkColumns的用法 android:stretchColumns="1" android: ...

  8. 详解Android SDK1.6中Text-To-Speech(TTS)语音朗读

    TextToSpeech简称 TTS,是Android 1.6版本中比较重要的新功能.将所指定的文本转成不同语言音频输出.它可以方便的嵌入到游戏或者应用程序中,增强用户体验. 在讲解TTS API和将 ...

  9. 详解android framework中StateMachine(HSM层次状态机)的实现

    [转载文章出处:https://segmentfault.com/a/1190000020386485?utm_source=tag-newest 作者:emonn] [最近在看状态机相关的问题,看到 ...

最新文章

  1. 人工机器:深度学习CNN到底实现了什么
  2. RequireJS使用注意地方
  3. 解决升级mac os X EI Capitan后遇到LibclangError: dlopen(libclang.dylib, 6): image not found.的问题...
  4. php字符串反转abcdefg_php中实现字符串翻转的方法
  5. 两个int()方法的区别
  6. rplidar 启动马达 c++_【玩码】刘作虎:一加7 Pro的横向线性马达,为安卓手机最大...
  7. cms的html调用,工作笔记三,phpcms几中HTML标签的调用
  8. 基于序列图像的三维体绘的视线投射算法
  9. php生成xml报错101,php编译报错大全
  10. NSIS中文乱码问题
  11. 熊猫烧香病毒源代码及分析
  12. python输入某年某月某日是一年的第几天_Python小例子——输入某年某月某日,判断这一天是这一年的第几天...
  13. 使用画图软件更改图片大小
  14. 什么是API、什么是SDK、他们有什么区别?
  15. 基于涂鸦智能开发的墨水屏座位管理器——2.嵌入式功能实现篇
  16. 第九周项目6-3:三色球问题
  17. 通信原理_2 确定信号分析
  18. PTA练习:谁先倒.(C语言)
  19. Jmeter+ant实现接口自动化(三)
  20. php获取股市交易日,个股交易日一年多少天?股市交易时间规定

热门文章

  1. 当我通勤时我该读什么
  2. 基于 Vue + Codemirror 实现 SQL 在线编辑器
  3. 输入姓名,程序输出欢迎信息。用 substring() 和 length() 获得名字的子串和长度分别输出姓和名字。
  4. 上海迪士尼乐园将上调票价,迪士尼乐园对人性的研究,真的很透彻。
  5. 函数序偶定义与高考招生
  6. 2023春季伴学挑战赛06C++算法:T3 谁要表演节目
  7. jquery添加删除表格行
  8. 【TOTP】TOTP算法(基于时间的一次性动态密码)原理介绍 简要逻辑实现说明
  9. python系列之面试者福音
  10. 模式识别+Matlab 感知器算法/LMSE算法