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

241 篇文章 5 订阅

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

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

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

 

2、realCall的enqueue()方法

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

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

3、dispatcher的enqueue()方法

 

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

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

 

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

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

4、

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值