OkHttp
1、execute和enqueue
execute是同步请求,enqueue是异步请求,请求后返回的结果都是在子线程中,需要对UI操作的化,需要用Handler处理
new Thread(new Runnanble(){
@override
public void run(){
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
// onResponse和onFailure方法都发生在工作线程(子线程)
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
...
}
}
});
2、原理&流程
OkHttp 面试题汇总_因为我的心的博客-CSDN博客_okhttp面试题
执行流程
- 通过构建者构建出OkHttpClient对象,再通过newCall方法获得RealCall请求对象.
- 通过RealCall发起同步或异步请求,由线程分发器dispatcher来决定是异步还是同步请求.
- 当发起同步请求时会将请求加入到同步队列中依次执行,所以会阻塞UI线程,需要开启子线程执行.
- 当发起异步请求时会创建一个线程池,并且判断请求队列是否大于最大请求队列64,请求主机数是否大于5,如果大于请求添加到异步等待队列中,否则添加到异步执行队列,并执行任务.
- 调用getResponseWithInterceptorChain()方法——>从队列中移除
- getResponseWithInterceptorChain()这个方法执行了责任链模式,通过5个拦截器,完成了请求和响应的处理
注意:一个请求只被执行一次,一个RealCall代表一个请求(response.body().string() 只能调用一次)


OkHttp 主要是通过 5 个拦截器和 3 个双端队列(2 个异步队列,1 个同步队列)工作。内部实现通过一个责任链模式完成,将网络请求的各个阶段封装到各个链条中,实现了各层的解耦。
5个拦截器
- RetryAndFollowUpInterceptor:处理错误,重新定向(在连接失败后进行重新连接,必要时进行重定向)
- BridgeInterceptor:将用户请求转换成网络请求,将网络响应转换成用户相应
- CacheInterceptor: 有缓存返回缓存,没有缓存就请求网络
- ConnectionInterceptor:打开连接,在连接池中寻找,没有的话,就新建
- CallServerInterceptor:拦截器链中的最后一个链点,通过网络请求服务器
3个双端队列
- runningAsyncCall:异步执行队列
- runningSyncCall: 同步执行队列
- readyAsyncCall:异步等待队列
OkHttp 的底层是通过 Socket 发送 HTTP 请求与接受响应,但是 OkHttp 实现了连接池的概念,即对于同一主机的多个请求,可以公用一个 Socket 连接,而不是每次发送完 HTTP 请求就关闭底层的 Socket,这样就实现了连接池的概念。而 OkHttp 对 Socket 的读写操作使用的 OkIo 库进行了一层封装
3、addNetworkInterceptor() 与 addInterceptor() 的区别
okhttp3 读书笔记——默认的线程池,addNetworkInterceptor() 与 addInterceptor() 的区别,复用连接池_一个有思想的搬运工-CSDN博客
addInterceptor():应用拦截器。是最先执行的拦截器,也就是用户自己设置request属性后的原始请求
1,不需要担心中间过程的响应,如重定向和重试.
2,总是只调用一次,即使HTTP响应是从缓存中获取.
3,观察应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match.
4,允许短路而不调用 Chain.proceed(),即中止调用.
5,允许重试,使 Chain.proceed()调用多次.
addNetworkInterceptor():网络拦截器。位于ConnectInterceptor和CallServerInterceptor之间,此时网络链路已经准备好,只等待发送请求数据
1,能够操作中间过程的响应,如重定向和重试.
2,当网络短路而返回缓存响应时不被调用.
3,只观察在网络上传输的数据.
4,携带请求来访问连接.
4、缓存处理——CacheInterceptor
缓存拦截器会根据请求的信息和缓存的响应的信息来判断是否存在缓存可用,如果有可以使用的缓存,那么就返回该缓存给用户,否则就继续使用责任链模式来从服务器中获取响应。当获取到响应的时候,又会把响应缓存到磁盘上面
4、连接池——ConnectInterceptor
- 判断当前的连接是否可以使用:流是否已经被关闭,并且已经被限制创建新的流;
- 如果当前的连接无法使用,就从连接池中获取一个连接;
- 连接池中也没有发现可用的连接,创建一个新的连接,并进行握手,然后将其放到连接池中
5、优缺点
优点: 内置连接池,支持连接复用,减少请求延迟;支持SPDY;利用缓存来避免重复的网络请求
缺点:处理的请求响应结果在子线程中,需要切到主线程才能操作UI; 传入调用比较复杂。
Retrofit
Carson带你学Android:网络请求库Retrofit使用教程(含实例讲解) - 简书
Retrofit底层实际还是使用okhttp进行的网路请求,只是它对请求接口进行了一个封装。
可以使用注解的方式配置网络请求参数,可以把相关的网络请求放在一个请求接口中(便于管理);
支持各种网络数据格式,对于服务器返回的数据,通过数据转换器能转换成我们期望的数据;
在回调处,封装了Handler,从子线程切换到了主线程;
使用了大量的设计模式,使得功能模块解耦,使用简单,但扩展性差
Rxjava
RxJava 是一个 基于事件流、实现异步操作(类似于 Android中的 AsyncTask 、Handler作用)的库
Carson带你学Android:这是一篇清晰易懂的Rxjava入门教程 - 简书
RxJava原理可总结为:
- 被观察者
(Observable)通过 订阅(Subscribe)按顺序发送事件 给观察者(Observer) - 观察者
(Observer)按顺序接收事件 & 作出对应的响应动作。具体如下图:


被折叠的 条评论
为什么被折叠?



