您的位置:首页 > 理论基础 > 计算机网络

Android OkHttp 源码解析 (四) Interceptor 应用层拦截器、网络层拦截器

2018-01-04 14:16 796 查看
介绍
官网图

我整理的思维导图

笔记
拦截器是什么
应用层拦截器
网络层拦截器

代码看区别
初始化

应用层拦截器

网络层拦截器

调用测试

输出日志

总结
源码

结论

介绍

官网图



我整理的思维导图

https://www.processon.com/view/link/5a4d9df4e4b078cf1ede543e

笔记

拦截器是什么?

拦截器是OkHttp 中提供一种强大机制,它可以实现网络监听、请求以及响应重写、请求失败重试等功能

应用层拦截器

不必要担心响应和重定向之间的中间响应。

通常只调用一次,即使HTTP响应是通过缓存提供的。

遵从应用层的最初目的。与OkHttp的注入头部无关,如If-None-Match。

允许短路而且不调用Chain.proceed()。

允许重试和多次调用Chain.proceed()。

网络层拦截器

允许像重定向和重试一样操作中间响应。

网络发生短路时不调用缓存响应。

在数据被传递到网络时观察数据。

有权获得装载请求的连接。

代码看区别

初始化 OkHttp 并添加 应用层拦截器 与 网络层拦截器

初始化

private final OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
.readTimeout(5, TimeUnit.SECONDS)
.addInterceptor(new ApplicationInterceptor())
.addNetworkInterceptor(new NetworkInterceptor())
.build();


应用层拦截器

public class ApplicationInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long startTimer = System.nanoTime();
KLog.e(String.format(Locale.CHINA,"Sending request %s on %s%n%s",request.url(),chain.connection(),request.headers()));
Response response = chain.proceed(chain.request());
long endTimer = System.nanoTime();
KLog.e(String.format(Locale.CHINA,"Received response for %s in %.1fms%n%s",response.request().url(),(endTimer - startTimer) / 1e6d,response.headers()));
return response;
}
}


网络层拦截器

public class NetworkInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
... 为了看出区别,与上面一致
}
}


调用测试

@OnClick(R.id.btn_async)
public void async(){
final Request request = new Request.Builder().url("http://www.publicobject.com/helloworld.txt").build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
KLog.e(e.getCause().toString());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
KLog.e(response.body().toString());
}
});
}


输出日志

为了更清晰,删除了一些其他日志

应用层拦截器

Sending request http://www.publicobject.com/helloworld.txt on null

Received response for https://publicobject.com/helloworld.txt in 3140.7ms


网络层拦截器

Sending request http://www.publicobject.com/helloworld.txt 
Sending request http://www.publicobject.com/helloworld.txt 
Received response for http://www.publicobject.com/helloworld.txt in

Sending request https://publicobject.com/helloworld.txt[/code] 

总结

源码

在拦截器中的顺序 后续文章会重点讲

//加入应用层拦截器
interceptors.addAll(client.interceptors());
//重试 重定向拦截器
interceptors.add(retryAndFollowUpInterceptor);
// 桥接和适配拦截器 主要用于补充网络请求头中必须的一些参数
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new
// 缓存拦截器
CacheInterceptor(client.internalCache()));
// 链接拦截器
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
// 网络层拦截器  interceptors.addAll(client.networkInterceptors());
}
// 向服务器发送请求,并最终返回Response对象供客户端使用
interceptors.add(new CallServerInterceptor(forWebSocket));


结论

其实原来就归功于顺序上

下面的文章会有介绍

1.应用层拦截器,只输出首次request 与 最后回调的 Response

2.网络层拦截器,每次输出request 与 Response (重定向等会多次调用)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android interceptor 源码