okhttp3.RealCall#getResponseWithInterceptorChain
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List
interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(new RetryAndFollowUpInterceptor(client));
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0,
originalRequest, this, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
boolean calledNoMoreExchanges = false;
try {
Response response = chain.proceed(originalRequest);
if (transmitter.isCanceled()) {
closeQuietly(response);
throw new IOException("Canceled");
return response;
} catch (IOException e) {
calledNoMoreExchanges = true;
throw transmitter.noMoreExchanges(e);
} finally {
if (!calledNoMoreExchanges) {
transmitter.noMoreExchanges(null);
这里有定义顺序,我们也可以从调用堆栈里面看到整个拦截器执行的顺序。
"OkHttp https://www.baidu.com/...@9689" prio=5 tid=0xae nid=NA runnable
java.lang.Thread.State: RUNNABLE
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:37)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:43)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at com.example.okhttptest.MainActivity$1.intercept(MainActivity.java:27)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:172)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().url("https://www.sina.com.cn/").build();
return chain.proceed(request);
}).build();
在 RealCall 中会按照顺序添加如下几个默认的 Interceptor 到责任链中用来完成基本功能:
用户设置的 Interceptor
RetryAndFollowUpInterceptor:失败重试及重定向
BridgeInterceptor:处理网络 Header、Cookie、gzip 等
CacheInterceptor:管理缓存
ConnectInterceptor:连接服务器
如果是 WebSocket 请求则添加对应的 Interceptors
CallServerInterceptor:数据发送/接收
执行顺序不一样,如果遇到304 重定向,netWorkInteceptors 能够监听到,而普通的application interceptors监听不到。application interceptors 只调用一次,不会处理到304.
RealInterceptorChain 调用 第一个 Interceptors 的 process 方法,第一个Interceptors 的process 方法中会调用下一个拦截器的intercept 方法,
okhttp3.internal.http.RealInterceptorChain#proceed() 注定会创建一个新的RealInterceptorChain,然后调用下一个拦截器的intercept 方法,并传入下一个chain,interceptor 处理完就调用chain 的process,chain 的 process 会获取到下一个拦截器,并传递下一次chain,就可以层层传递。
OkHttp https://www.baidu.com/…
public abstract class NamedRunnable implements Runnable {
protected final String name;
public NamedRunnable(String format, Object... args) {
this.name = Util.format(format, args);
@Override public final void run() {
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(name);
try {
execute();
} finally {
Thread.currentThread().setName(oldName);
protected abstract void execute();
https://zhuanlan.zhihu.com/p/104813091
其实从名字我们大概能猜到一些奥妙,Bridge中文意思即桥梁,连接的意思,那在这里其实就是连接应用程序和服务器的桥梁,我们发出的请求将会经过它的处理才能成为一个服务器能识别的网络请求;所以它的具体作用就是在真正进行网络请求前对我们的请求头做一些设置,比如设置请求内容长度,编码,gzip压缩,cookie等,获取响应后为响应添加一些响应头信息
我有一个OKHTTP客户机,它使用我的自定义网络拦截器将令牌插入请求头中。我不断地得到例外E/AndroidRuntime: FATAL EXCEPTION: OkHttp DispatcherProcess: com.edstart.tazuzu, PID: 32093java.lang.NullPointerException: interceptor com.edstart.tazuzu.R...
Okhttp解析—Interceptor详解
Interceptor可以说是okhttp的精髓之一,Okhttp重写请求/响应、重试、缓存响应等操作,基本都是在各个Interceptor中完成的,上篇文章分析Okhttp运行流程时只是简单带过,那么这篇文章就来详细分析下Interceptor以及拦截器链机制。
一、Interceptor以及InterceptorChain
* Ob...
使用OkHttp3发送Http请求并获得响应的过程大体为:
创建OkHttpClient对象。OkHttpClient为网络请求执行的一个中心,它会管理连接池,缓存,SocketFactory,代理,各种超时时间,DNS,请求执行结果的分发等许多内容。
创建Request对象。Request用于描述一个HTTP请求,比如请求的方法是"GET"还是"POST",请求的UR
在本系列的上一篇文章中,我们走读了一遍okhttp的源码,初步了解了这个强大的网络框架的基本执行流程。
不过,上一篇文章只能说是比较粗略地阅读了okhttp整个执行流程方面的源码,搞明白了okhttp的基本工作原理,但并没有去深入分析细节(事实上也不可能在一篇文章中深入分析每一处源码的细节)。那么本篇文章,我们对okhttp进行深入地分析,慢慢将okhttp中的各项功能进行全面掌握。
今天文章中的源码都建在上一篇源码分析的基础之上,还没有看过上一篇文章的朋友,建议先去阅读 网络请求框架OkHttp3全解系列
对于http请求我们都知道开始于TCP链接的三次握手然后传输数据然后释放,如下图
而当我们开启连接复用keep-alive后就是指在上一次链接不立马断开链接在超时范围内复用connection在timeout 空闲的时间内就会复用相同的Request来减少握手大幅度提高了网络请求效率;如下图
而在Okhttp3中是怎么做到连接池复用的,本文从源码(版本v4.9.3)角度来进行探索
Okhttp3的连接池复用、清理、回收机制
连接池的代码类位于okhttp3.ConnectionPool,该类作为默
Android中发送HTTP请求,报错如下E/AndroidRuntime: FATAL EXCEPTION: mainProcess: cn.iyikong.managementterminal, PID: 4447android.os.NetworkOnMainThreadExceptionat android.os.StrictMode$AndroidBlockGuardPolicy.onN...
在调用 okhttp3 时抛出如下异常:D/NetworkSecurityConfig: No Network Security Config specified, using platform defaultW/System.err: java.io.IOException: unexpected end of stream on Connection{mirrors.shu.edu.cn:80...
Okhttp3是非常火爆的一个网络请求框架,虽然你90%配合了Retrofit,但大概率你在指定Retrofit的网络请求客户端的时候,也会使用Okhttp3此篇用于记录在使用Okhttp3中遇到的异常,会不断更新...java.lang.NoClassDefFoundError: Failed resolution of: Lokhttp3/internal/http/HttpEngine;at...
okhttp3的拦截器机制为开发者提供了方便的功能定制,比如日志打印、拦截请求、拦截响应等等
总共有两种拦截器:
ApplicationInterceptor,NetworkInterceptor
比如实现日志拦截代码:
public class LoggingInterceptor implements Interceptor{
private ...
RetryAndFollowUpInterceptor – 失败和重定向拦截器
BridgeInterceptor – 封装request和response拦截器
CacheInterceptor – 缓存相关的过滤器,负责读取缓存直接返回、更新缓存
ConnectInterceptor – 连接服务,负责和服务器建立连接 这才是真正的请求网络
CallServerInterc
关于Okhttp的介绍以及牛逼之处笔者不进行科普了,不懂的自行戳http://blog.csdn.net/lmj623565791/article/details/47911083
在使用Okhttp的过程中频繁的发起Http请求时偶尔会看到如下的错误
ERROR [IOException]-[120]
java.io.IOException: unexpected end of