okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法

1、okhttp同步和异步请求的差别不是很大,同步调用的是execute(),而异步 调用的是enqueue()方法,但是这两者的内部实现机制有很多区别。

第一步创建OkhttpClient这个对象,第二步创建Request这个请求报文类,第三步根据request构建一个http请求Call类,第四步会调用enqueue()这个方法执行异步的请求。需要注意的是前三步都没有发起实际的网络请求,只是做了一些网络请求前期的操作,真正的网络请求还是在第四步当中。通过调用enqueue()将实际的请求call添加到队列当中。在enqueue(new callback())这个方法当中会传入一个callback()进来,这个callback对象就是用来请求结束以后进行接口回调的。

由于call就是一个接口,所以它的具体实现要到realCall当中

okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法_第1张图片

 

2、realCall的enqueue()方法

okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法_第2张图片

这个方法使用了synchronized关键字,也就是说它锁住了当前对象,当前这个对象就是realCall这个对象,然后会对executed这个字段进行判断。executed这个字段代表什么呢?它代表 当前这个realCall实例有没有执行过,当它为true的时候代表当前这个实例已经执行过了,这时候会抛出异常。可见,前一步得到的call对象只能被执行一次。这和后面要讲述的连接池的概念有一定的关系

最后一步根据传入进来的responseCallback对象封装成了一个AsyncCall对象。AysncCall对象继承自NamedRunnable,其实AysncCall就是一个runnable。再构建好AsyncCall对象以后,就调用dispatcher,dispatcher其实就是一个分发器类,调用它的enqueue()方法来完成实际的异步请求。dispatcher在哪里定义的呢?在创建OkHttpClient对象的内部类Builder时,在builder的构造方法里已经实例化好了这个对象。

okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法_第3张图片

okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法_第4张图片

3、dispatcher的enqueue()方法

okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法_第5张图片

 

enqueue()这个方法内部使用了synchronized这个关键字,并且这个方法传入了一个Runnable的实现类AysncCall实例对象。

首先会判断runningAysncCalls异步请求的数量是否小于最大请求数,并且运行的最大主机的数量runningCallsForHost是否小于最大主机的运行数量,如果满足这个条件,就会将这个异步请求添加到正在运行的异步请求队列当中,然后再通过线程池去执行这个异步请求。这个判断的意思是,当要发起一个异步网络请求的时候,它首先会判断当前正在请求的runnable个数是否小于规定的最大请求数maxrequest,而maxrequest已经规定好了,是64,如果是小于64的话,并且当前网络请求小于maxRequestsPerHost 规定的5个请求的这两个条件时,就会把当前的异步请求添加到异步请求队列当中,然后通过线程池去执行这个call,如果不是就走else这个逻辑,把它加到等待队列readyAsyncCalls中。

 

注:runningAsyncCalls其实是在Dispatcher中定义好的,它其实是一个队列,它代表的是正在运行的任务,它的作用是判断并发请求的数量。

readyAsyncCalls代表的是缓存请求队列。

okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法_第6张图片

4、

okhttp网络框架源码解析四okhttp网络框架源码解析异步请求执行流程之enqueue()方法_第7张图片

 

 

你可能感兴趣的:(笔记,Android)