OKHTTP

      android的网络请求框架很多,但是自android4.4之后系统内置了okhttp,可见okhttp的分量之重!这篇文章以okttp3.8.1的源码,简单解析一下okhttp的运作流程:

首先发起一个简单的异步请求,代码如下

其基本步骤就是创建OkHttpClient、Request和Call,最后调用Call的enqueue()方法。但是每次这么写很麻烦,肯定是要进行封装的。需要注意的是onResponse回调并非在UI线程。如果想要调用同步GET请求,可以调用Call的execute方法。

当调用client的newcall方法时,实际上是创建了一个RealCall对象:

当我们调用call的异步方法enqueue的方法进行网络请求的时候,实际上是调用的RealCall对象的enqueue方法

可以看到这一行 client.dispatcher().enqueue(new AsyncCall(responseCallback));最终的请求是dispatcher来完成的

看看这个Dispatcher,他主要是要维护了如下的变量来控制并发的请求任务:

当调用realcall的enqueue的方法时,最终会由dispatcher来调用自身的enqueue,看看dispatcher内的该方法实现:

当正在运行的异步请求队列中的数量小于64并且正在运行的请求主机数小于5时,把请求加载到runningAsyncCalls中并在线程池中执行,否则就加入到readyAsyncCalls中进行缓存等待。

看一下这个AsyncCall,它是RealCall的内部类,其内部也实现了execute()方法

AsyncCall有一行关键的代码需要我们注意一下:Response response = getResponseWithInterceptorChain():

可以看到在这个方法中体现了okhttp最核心的功能:拦截器。在调用chain.proceed之前会设置所有的拦截器,包括okhttp自带的和用户自己设置的拦截器

这里有5个okhttp自带的拦截器:

  • RetryAndFollowUpInterceptor
    在网络请求失败后进行重试
    当服务器返回当前请求需要进行重定向时直接发起新的请求,并在条件允许情况下复用当前连 接
  • BridgeInteceptor
    设置内容长度,内容编码
    设置gzip压缩,并在接收到内容后进行解压。省去了应用层处理数据解压的麻烦
    添加cookie
    设置其他报头,如User-Agent,Host,Keep-alive等。其中Keep-Alive是实现多路复用的必要步骤
  • CacheInterceptor
    当网络请求有符合要求的Cache时直接返回Cache
    当服务器返回内容有改变时更新当前cache
    如果当前cache失效,删除
  • ConnectInterceptor
    为当前请求找到合适的连接,可能复用已有连接也可能是重新创建的连接,返回的连接由连接池负责决定。
  • CallServerInterceptor
    负责向服务器发起真正的访问请求,并在接收到服务器返回后读取响应返回。

再看一下这个RealInterceptorChain的proceed方法:

proceed方法每次从拦截器列表中取出拦截器。当存在多个拦截器时都会在上面代码

Response response = interceptor.intercept(next);

处阻塞,并等待下一个拦截器的调用返回。

所以一次请求在所有拦截器的总体执行流程如下:

拦截器是一种能够监控、重写、重试调用的机制。通常情况下,拦截器用来添加、移除、转换请求和响应的头部信息。比如将域名替换为IP地址,在请求头中添加host属性;也可以添加我们应用中的一些公共参数,比如设备id、版本号,等等。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值