OkHttp基本用法:
OkHttpClient mOkHttpClient = new OkHttpClient();
//使用budiler模式构建Request
Request mRequest = new Request.Builder().url("").build();
//将Request封装到call中
Call call = mOkHttpClient.newCall(mRequest);
//异步请求
call.enqueue(new Callback(){});
总结起来也就是
1、创建Request
2、发送Request
3、获得Response
发送Request主要涉及到:Dispatcher、RealCall(AnsycCall是RealCall的内部类,继承自NamedRunnable)
Dispatcher中最终执行任务executorService().execute(call); 会调用到AsyncCall的execute方法,里面有一个重量级方法
getResponseWithInterceptorChain
这个方法是用来获取Response的。
getResponseWithInterceptorChain方法最终调用getResponse方法
Response getResponse(Request request, boolean forWebSocket) throws IOException { ...// engine = new HttpEngine(); ...// engine.sendRequest(); engine.readResponse(); }
HttpEngine也是极其重要的方法。
***OkHttp工作的大致流程
1)构建OkHttpClient,Request,Call
2)通过Call发起同步或者异步请求:call.execute() call.enqueue
3)OkHttp会通过Dispatcher对所有的RealCall(Call的具体实现类)进行统一管理,并通过execute()或者enqueue()方法对同步或者异步请求进行处理
4)execute()、enqueue()方法最终都会调用RealCall中的getResponseWithInterceptorChain()方法,从拦截器中获取返回结果;
5)拦截器链中,依次通过RetryAndFollowUpInterceptor(重定向拦截器)、BridgeInterceptor(桥接拦截器)、CacheInterceptor(缓存拦截器)、ConnectionInterceptor(连接拦截器)、CallServerInterceptor(网络拦截器)对请求依次处理,与服务器建立连接后,获取返回数据,再经过上述 拦截器依次处理后,最后将结果返回给调用方。
注:拦截器是将请求一层一层向下传,直到有一层能够得到Response 就停止,并将Response 向上面的拦截器传递, 然后各个拦截器会对 Response 进行一些处理,最后传到 RealCall 类中返回。
CacheInterceptor
负责读取缓存 和 更新缓存
在请求阶段:
1.读取候选缓存cacheCandidate
2.根据originRequest 和 cacheResponse创建缓存策略CacheStrategy;
3.根据缓存策略,来决定是否使用网络或者使用缓存 或者 返回错误。
具体的缓存策略就是http的缓存策略
在结果返回阶段:负责将网络结果进行缓存(使用于DiskLruCache)
***连接池原理
因为http是基于TCP的, TCP连接时需要经过三次握手,为了加快网络访问速度,我们可以在Request的header中将Connection设置为keepalive来复用连接。
OkHttp支持5个并发keeplive,默认链路生命为5分钟(链路空闲后,保持存活的时间),连接池有ConnectionPool实现,对连接进行回收 和 管理。
总结:
Okhttp的底层是通过Java的Socket发送Http请求 与 接收响应的,但是Okhttp实现了连接池的概念,即对于同一主机的多个请求,其实可以使用一个Socket连接,而不是每次发送完Http请求就关闭底层的Socket,这样就实现了连接池的概念。而OkHttp对Socket的读写操作使用的Okio库进行了封装。
涉及到的设计模式
责任链模式:拦截器链
单例模式:线程池
观察者模式:各种回调监听
策略模式:缓存策略
构造者模式:OkHttpClient的构建过程
外观模式:OkHttpClient封装了很多类对象
工厂模式:Socket的生产
OkHttp的优势
功能方面:功能全面,满足了网络请求的大部分需求
网络优化方面:1)内置了连接池,支持连接复用 2)支持gzip压缩响应体; 3)通过缓存避免重复的请求; 4)支持http2,对一台机器的所有请求共享同一个Socket
扩展性方面:拦截器模式使得我们很容易添加一个自定义拦截器对请求 和 返回结果 进行处理。
注:拦截器作用:1)获取请求的Request; 2)处理Request获取Response