OkHttp面试总结

2,877 阅读3分钟
原文链接: www.jianshu.com

本着针对面试,不负责任的态度,写下《面试总结》系列。本系列记录面试过程中各个知识点,而不是入门系列,如果有不懂的自行学习。

转载请标明出处,本文地址: https://www.jianshu.com/p/6ed08f540741

不负责任面试系列


更新列表

日期 修改内容
2019年3月22日 修改部分显示格式
责任链模式Demo


Okhttp是对Socket的封装。有三个主要的类,Request,Response,Call
默认使用new OkHttpClient() 创建初client对象。
如果需要初始化网络请求的参数,如timeout,interceptor等,可以创建Builder,通过builder.build() 创建初client对象。

使用new Request.Builder().url().builder()创建初requst对象。

通过client.newCall()创建出call对象,同步使用call.excute(), 异步使用call,enqueue(). 这里Call是个接口,具体的实现在RealCall这个实现类里面。

Okhttp的高效体现在,okhttp内有个Dispatcher类,是okhttp内部维护的一个线程池,对最大连接数,host最大访问量做了初始定义。维护3个队列及1个线程池

readyAsyncCalls

待访问请求队列,里面存储准备执行的请求。

runningAsyncCalls

异步请求队列,里面存储正在执行,包含已经取消但是还没有结束的请求。

runningSyncCalls

同步请求队列,正在执行的请求,包含已经取消但是还没有结束的请求。

ExecutorService

线程池,最小0,最大Max的线程池

在执行call.excute()的时候,调用到realcall类里的excute方法,这个是同步方法,在方法的第一行就加了锁,判断executed标记,如果是true就抛出异常,保证一个请求只被执行一次。false的话继续向下执行。调用client.dispatcher.excute()进入到dispatcher类中,向runningSyncCalls队列中添加当前这个请求。执行结束会调用finished方法

如果是异步操作,会创建一个RealCall.AsyncCall对象,AsyncCall继承的NamedRunnable接口,NamedRunnable是个runnable。进入到Dispatcher的enqueue()方法中,首先判断线程池中线程的数据,host的访问量,如果都没有达到那么加入到runningAsyncCalls中,并执行。否则加入到readyAsyncCalls队列中。
finished方法,如果是异步操作,promoteCall方法,promoteCalls()中用迭代器遍历readyAsyncCalls 然后加入到runningAsyncCalls

RealConnection

真正的连接操作类,对soket封装,http1/http2的选择,ssl协议等等信息。一个recalconnection就是一次链接

ConnectionPool

链接池,管理http1/http2的连接,同一个address共享一个connection,实现链接的复用。

StreamAlloction

保存了链接信息,address,HttpCodec,realconnection,connectionpool等信息

在realCall中 getResponseWithInterceptorChain()创建并开启拦截器链

Okhttp中的拦截器,默认的分为5种

  • RetryAndFollowUpInterceptor
    做网络失败重连,但是并不是所有的请求都需要重连,根据响应码。MAX_FOLLOW_UPS=20最大重连次数
    在intercept方法中创建了StreamAllocation对象,并调用chain.proceed方法,执行下一个拦截器,对request进行处理,并返回response。
  • BirdgeInterceptor
    初始化信息,添加请求头等,例如gzip,keep-alive,返回的response进行解压
  • CacheInterceptor
    内部有Cache类,处理缓存操作,intercache内部类,disklrucache算法等
    重点是不缓存非get的请求。
    CacheStrategy缓存策略类,通过工厂模式获取
  • ConnectionInterceptor(建议重点阅读源码)
    建立链接,使用之前创建好的StreamAllocation,初始化httpcodec,realConnection。内部使用了类似gc标记清理算法,对无用的connection进行标记,StramAlloction渐渐变成0,线程池检测并回收,保证多个健康的keep-alive链接
  • CallServerInterceptor
    发起真正的网络请求,解析返回的数据
    http写入网络IO流,从网络IO流中读取返回给客户端的数据。

OkHttp中的设计模式

单例、Builder、策略、责任链、观察者

思考: 策略与简单工厂的区别


相关面试题
  1. 责任链模式