OkHttp3

2020-04-06  本文已影响0人  iDcareU

1、OkHttp的使用

以下几篇写得很清楚,看完收获很大             //2020/4/7 更新

https://juejin.im/post/5bc89fbc5188255c713cb8a5#heading-10

https://blog.piasy.com/2016/07/11/Understand-OkHttp/index.html


1、配置build.gradle和网络权限

implementation("com.squareup.okhttp3:okhttp:4.4.0")

2、Get a URL &Post to a Server 这是GitHub上的两个例子,一个是同步get,另一个是异步post。更多参考 

https://square.github.io/okhttp/recipes/


2、源码分析

流程图

图来自https://blog.piasy.com/2016/07/11/Understand-OkHttp/index.html,大神讲得很好。
1、创建OkHttpClient()对象

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory{...}

OkhttpClient的构造方法如下

public OkHttpClient() { this(new Builder());}   、OkHttpClient(Builder builder) {...}

OkHttpClient也有很多属性和方法(这些几乎都是getter方法),这里不列举

 //构造函数里面通过自身的Builder类完成构造,给出一个简单的接口给用户使用,通常我们使用的 是默认的参数构造

Builder类中有很多属性,通过Builder内的方法设置属性的值,(思考:是不是建造者模式?)

https://www.jianshu.com/p/8d69fd920166// https://www.jianshu.com/p/3d1c9ffb0a28

Builder的构造函数有Builder(OkHttpClient okHttpClient){.......}、public Builder(){......}

Builder类(这个Builder是OkHttpClient的内部类)里面的属性跟OkHttpClient里面的属性大多相似 ,另外,Builder有设置这些属性的很多方法

OkHttpClient通过无参的Builder类设置其默认的属性,如果要改变属性,则使用Builder内一系列的方法。

//通过上面的步骤,OkHttpClient就是使用Builder来构造,而Builder可以是无参的,也可以参数是OkHttpClient

/??这个猜测是用来复用已存在的OkHttpClient) eg:已经存在OkHttpClient client, 此时OkHttpClient.Builder builder = new OkHttpClient.Builder(client); OkHttpClient client2 = new OkHttpClient(builder);此时client2 跟client的属性相同,以上属猜测??/

2、Request构建

同样采用建造者模式,OkHttpClient类的构造过程类似。

3、Call构建

OkHttpClient里面的方法代码如下

public Call newCall(Request request) {

    return RealCall.newRealCall(this, request, false /* for web socket */);

  }//Call是接口类,RealCall继承Call,此时RealCall已经包含OkHttpClient和request.

4、RealCall的执行enqueue()、execute()

先看execute(),参考https://blog.piasy.com/2016/07/11/Understand-OkHttp/index.html,execute做了四步:(代码版本不一样)

1、检查这个 call 是否已经被执行了,每个 call 只能被执行一次,如果想要一个完全一样的 call,可以利用 call#clone 方法进行克隆。

2、利用 client.dispatcher().executed(this) 来进行实际执行,dispatcher 是刚才看到的 OkHttpClient.Builder 的成员之一,它的文档说自己是异步 HTTP 请求的执行策略,现在看来,同步请求它也有掺和。

3、调用 getResponseWithInterceptorChain() 函数获取 HTTP 返回结果,从函数名可以看出,这一步还会进行一系列“拦截”操作。

4、最后还要通知 dispatcher 自己已经执行完毕。

enqueue() 先检查Call是否执行,再通过dispatch执行,dispatch主要是用于异步执行,再看看AsyncCall和dispatch

AsyncCall给异步执行添加了一个回调接口

至于dispatch,对于同步请求把它加入到runningSyncCall队列,对于异步请求,先把它加入到readyAsyncCall队列,然后执行promoteAndExecute函数,它的作用是把readyAsyncCall中的队列拿出,判断是否可以执行,如果可以把它加入到runningAsyncCall队列并交给线程池处理。

上一篇下一篇

猜你喜欢

热点阅读