前言:现在的Android项目基本上都是以OkHttp来进行网络通信的(retrofit也是基于okhttp的)
下面记录下okhttp3中的一些实现方式和原理。

工作流程


以这张图出发,说一下几个注意的点:

(1) 建议让 OkHttpClient 保持单例,用同一个 OkHttpClient 实例来执行你的所有请求,因为每一个 OkHttpClient 实例都拥有自己的连接池和线程池,因此为每一个请求都创建一个client是不必要的且影响软件效率。
下面我们来看看 new OkHttpClient() 的时候干了什么。从使用方面入手,下面就是创建一个client的常用手法:

#创建一个client主要有以下两种方式
OkHttpClient client = new OkHttpClient();
OkHttpClient client1 = new OkHttpClient.Builder().build();

这两种方式都可以实例化一个client对象,下面看看他们分别怎么做的:

直接调用 new OkHttpClient() 后,也会隐式的创建一个builder对象,然后在OkHttpClient构造方法中初始化一堆数据。如果是new OkHttpClient.Builder().build() 这种方式创建client的话,相当于显式的创建了builder,当然最后build的时候也是返回了一个client对象,如下所示。

他们的区别是 如果使用builder来构建的话,可以在后面追加一些拦截器进去。

(2)上诉步骤中创建了client了,接下来就是创建Request对象,Request这个类可以看做一个请求的封装,里面有url,body,headers等字段。Request对象的创建也使用到了建造者模式。按照get请求和post请求的区别,我们有如下两种创建Request的写法:

     //get请求Request request = new Request.Builder().url("http://www.baidu.com").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {//...}@Overridepublic void onResponse(Call call, Response response) throws IOException {//...}});//post请求MediaType mMediaType = MediaType.parse("text/x-markdown; charset=utf-8");RequestBody body = RequestBody.create(mMediaType,  "test");Request request1 = new Request.Builder().url("http://www.baidu.com").post(body).build();

GET请求是默认使用的请求方式,因此不需要requestbody,但POST请求需要通过post(RequestBody)方法传入对应的请求体。请看他们所属的builder:

下面我们继续追一下post方法中干了什么:

可以看到,这里将原本默认为GET的method修改为了POST,然后还把body给赋值了。

(3)至此,我们有了发送请求的 OkHttpClient ,也有了 Requset,那么就可以执行发送请求了。

client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {//...}@Overridepublic void onResponse(Call call, Response response) throws IOException {//...}});Call call = client1.newCall(request1);call.enqueue();

我们使用newCall就可以构造一次发送请求,然后接收其回调结果即可。
首先我们先来看看newCall方法干了什么:

他调用了realcall类的方法,创建了一个新的realcall对象,这个对象持有我们当前所使用的httpclient和request。然后通过realcall对象,我们创建出Transmitter类。

此时我们有了realcall对象,我们可以选择调用execute()方法或者enqueue()方法。如果选择execute的话,则会马上发送这条请求,并返回response给我们。

若是选择enqueue方法则会要求你传入一个接口,因为使用enqueue()方法的话,我们的请求具体执行交给了Dispatcher类来执行。

dispatcher任务任务调度器会将其存入待执行的请求队列中,然后条件允许的话再加入到运行中的请求队列(runningAsyncCalls)中,然后将这个请求放到任务调度器中的线程池中进行消费,具体过程如下:

01.加入准备任务队列中

02.判断其是否具有执行条件

03.确认执行的话,会进入RealCall的executeOn方法中

04. 假如03步正确执行了,那么会在此确认执行结果

至此,若是成功返回了response的话,就会触发接口onresponse,我们上层就能收到结果了。 但上图中的getResponseWithInterceptorChain()方法还值得细说。

(4)进入拦截链流程getResponseWithInterceptorChain方法
这个方法返回的是response对象,我们看看它都做了些什么:

可见在 getResponseWithInterceptorChain 方法中,创建了一系列拦截器,然后我们的request请求通过拦截器调用链的拦截后,最后才会返回Response对象 就是上面chain.proceed(originalRequest)方法执行完成之后返回。
在看chain.proceed方法前我们先简单介绍下各个拦截器有什么用:(按代码顺序)

每个拦截器的作用可以参考这篇文章

本文入门式的介绍了下okp的原理,后续会补充渐渐深入的文章…

END

安卓Okhttp3源码的简单分析相关推荐

  1. android6.0源码目录简单分析

    http://blog.csdn.net/wo_sxn/article/details/50532071 http://blog.csdn.net/fengliang191/article/detai ...

  2. 安卓10源码开发定制(29)手电筒控制源码分析

    一.前言 最近突发奇想,想做一个项目.将闲置手机变成可以利用的智能家居设备,比如在家里面通过手机App控制另一台手机的手电筒开和关(当做电灯泡)等等操作.先从最简单的功能开始研究,控制手电筒开始. 二 ...

  3. 安卓源码,安卓开发,跑步打卡项目app源码,包括源码和简单文档

    安卓源码,安卓开发,跑步打卡项目app源码,包括源码和简单文档 ID:6975644491117436Robergean

  4. 安卓源码,安卓开发,跑步打卡项目app源码,包括源码和简单文 档

    安卓源码,安卓开发,跑步打卡项目app源码,包括源码和简单文 档

  5. 【安卓系统源码学习之permission】 系统源代码AndroidManifest.xml分析之permission解读

    上一节,我们讲到了怎么去查找安卓源码中AndroidManifest.xml文件,打开这个文件,你会发现里面有很多<permission ... />的标签,如下图所示: 这个是用来做什么 ...

  6. OkHttp3源码详解

    前言:为什么有些人宁愿吃生活的苦也不愿吃学习的苦,大概是因为懒惰吧,学习的苦是需要自己主动去吃的,而生活的苦,你躺着不动它就会来找你了. 一.概述 OKHttp是一个非常优秀的网络请求框架,已经被谷歌 ...

  7. OKHTTP3源码和设计模式(下篇)

    ​ 在<OKHTTP3源码和设计模式(上篇)>,中整体介绍了 OKHttp3 的源码架构,重点讲解了请求任务的分发管理和线程池以及请求执行过程中的拦截器.这一章我们接着往下走认识一下 OK ...

  8. OkHttp3源码解析(三)——连接池复用

    OKHttp3源码解析系列 OkHttp3源码解析(一)之请求流程 OkHttp3源码解析(二)--拦截器链和缓存策略 本文基于OkHttp3的3.11.0版本 implementation 'com ...

  9. JAVA源码优化、分析工具

    JAVA源码优化.分析工具 一.11款用于优化.分析源代码的Java工具 1. PMD from http://pmd.sourceforge.net/ PMD能够扫描Java 源代码,查找类似以下的 ...

最新文章

  1. 利用partition分组查询 查询每个分组第一条数据
  2. 【数字信号处理】离散时间系统因果性 ( 因果性概念 | 充要条件及证明 )
  3. BZOJ.1032.[JSOI2007]祖码(区间DP)
  4. hdu 5072 Coprime
  5. 一文看懂Python(二)-----字符串篇
  6. php签名墙代码,我们是一家人(签名墙)
  7. jQuery.sap.declare(cus.crm.notes.ext.Component);
  8. python实现监控电脑打开网页_Python轻松实现动态网页爬虫(附详细源码)
  9. [New Portal]Windows Azure Virtual Machine (14) 在本地制作数据文件VHD并上传至Azure(1)
  10. Starling框架帮助手册中文版(PDF下载)
  11. ie浏览器怎么取消代理浏览器_微软和IE渐行渐远,IE浏览器终将成为回忆
  12. 多年心路历程见证从技术小白到收获BAT等大厂研发offer,分享一些经验和感悟...
  13. (笔记)电路设计(六)之稳压二极管的应用
  14. 北斗/RTK高精度定位系统的优势及适用场景
  15. 【JAVA面试题-阿辉】try catch finally , try 里有 return , finally 还执行么?
  16. kvphone软电话安装包(ip电话)
  17. 软件设计模式——监听模式
  18. Adobe Photoshop CC 2017 (32 Bit) 软件安装
  19. VS code C/C++扩展包依赖cpptools-win32.vsix离线安装
  20. [计算机视觉实验一]基本的图像操作与处理

热门文章

  1. 用HTML搭建3D立体相册网页,可放大缩小
  2. Cmn递推函数c语言,Cmn排列组合 高三数学知识点总结归纳5篇精选
  3. 抑郁研究所融资历程分享--以太一堂--直播课
  4. 查看mysql数据库的定时任务_mysql数据库的定时任务
  5. 关于PGP的简单使用
  6. 【mac】MacBook使用快捷键
  7. 初中计算机卡片的制作教案,《运用Word制作电子贺卡》教学设计
  8. linux安装sqlserver
  9. vultr连接不上ssh的解决方案
  10. vultr 安装docker