OkHttp源码核心类之一:拦截器简述
正文
OkHttp是什么
OkHttp是时下非常流行的网络编程框架,由行业巨佬
Square
公司开源,很多其他的流行框架比如retrofit
的底层也是okhttp,只不过使用了注解反射动态代理将其进行了封装。
流行版本为:3.10.0,最新版本为:4.0.1,只不过将实现语言从java改成了kotlin。
相对于其他网络框架,有如下优点:
- 支持
Spdy
、Http1.X
、Http2
、Quic
以及WebSocket
- 连接池复用底层
TCP(Socket)
,减少请求延时- 无缝的支持
GZIP
减少数据流量- 缓存响应数据减少重复的网络请求
- 请求失败自动重试主机的其他
ip
,自动重定向
OkHttp怎么用
添加gradle依赖
dependencies {
....
implementation("com.squareup.okhttp3:okhttp:4.0.1")
}
Java调用(同步请求,异步请求)
public class MyRequest {
/**
* 异步请求
*/
public void sendReqAsync() {
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url("http://www.baidu.com").build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
Log.d("sendReqTag", "onFailure:" + e.getLocalizedMessage());
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String s = new String().concat(response.code() + "/n")
.concat(response.message() + "/n")
.concat(response.body().string());
Log.d("sendReqTag", "onSuccess/n " + s);
}
});
}
/**
* 同步请求
*/
public void sendReqSync() {
OkHttpClient client = new OkHttpClient.Builder().build();
Request request = new Request.Builder().url("http://www.baidu.com").build();
Call call = client.newCall(request);
try {
Response response = call.execute();
String s = new String().concat(response.code() + "/n")
.concat(response.message() + "/n")
.concat(response.body().string());
Log.d("sendReqTag", "onSuccess/n " + s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
OkHttp的简单使用方法大致使用如上,其中也有一些细节需要注意:
1、在应用层使用OkHttp,必然会涉及到4个重要元素:
- OkHttpClient类(产生OkHttp客户端实例)
- Request类(请求封装)
- Call类(网络任务封装,并决定是要
同步执行
还是异步执行
,注意,同步请求不
可以放在主线程
中,但是异步请求可以 )- Response类(网络任务执行之后的回调)
2、执行网络请求必须在manifest中申请
INTERNET
权限,不然会抛异常.3、完整的一个请求执行出去,流程如下图:
OkHttp源码核心类之一:分发器详解
上述,提到Call类,可以选择性执行 同步或者异步请求,但是无论同步异步,都一定会经过一个门户:"分发器" :
索引进源码(okhttp v3.10.0):
虽然用户不需要直接操作分发器,但是 分发器,作为OkHttp
架构的一个门户层,是所有请求的必经之路,其中的代码还是有必要了解细节的。
同步请求
进入分发器 Dispatcher
之后, 会执行 getResponseWithInterceptorChain()
来执行这个Call
任务,得到一个Response
,其中的细节分为两步:
1、
client.dispatcher().executed(this);
,进入源码可以看到 仅仅是执行了runningSyncCalls.add(call);
,将call对象加入到了一个双端队列Deque<RealCall> runningSyncCalls
中。
2、getResponseWithInterceptorChain()
是执行网络请求的核心内容,涉及到拦截器,在这一节上暂时不详述。
同步请求的执行步骤十分简单,将任务加入到 runningSyncCalls列表,并且直接执行核心方法,同步阻塞拿到response。
《960全网最全Android开发笔记》
《379页Android开发面试宝典》
《507页Android开发相关源码解析》
因为文件太多,全部展示会影响篇幅,暂时就先列举这些部分截图
原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/162374.html