开源框架之一第一篇:OKhttp解析,这些你又了解多少呢?

public OkHttpClient() {
this(new Builder());
}

原来是方便我们使用,提供了一个“快捷操作”,全部使用了默认的配 置。 OkHttpClient.Builder 类成员很多,后面我们再慢慢分析,这里先暂时略 过:

public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
proxySelector = ProxySelector.getDefault();
cookieJar = CookieJar.NO_COOKIES;
socketFactory = SocketFactory.getDefault();
hostnameVerifier = OkHostnameVerifier.INSTANCE;
certificatePinner = CertificatePinner.DEFAULT;
proxyAuthenticator = Authenticator.NONE;
authenticator = Authenticator.NONE;
connectionPool = new ConnectionPool();
dns = Dns.SYSTEM;
followSslRedirects = true;
followRedirects = true;
retryOnConnectionFailure = true;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
}

2.2.发起 HTTP 请求

String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}

OkHttpClient 实现了 Call.Factory ,负责根据请求创建新的 Call 。
那我们现在就来看看它是如何创建 Call 的:

/**

  • Prepares the {@code request} to be executed at some point in the future.
    */
    @Override public Call newCall(Request request) {
    return new RealCall(this, request);
    }

如此看来功劳全在 RealCall 类了,下面我们一边分析同步网络请求的过程,一边 了解 RealCall 的具体内容。

2.2.1.同步网络请求

我们首先看 RealCall#execute

@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException(“Already Execu ted”);
// (1)
executed = true;
}
try {
client.dispatcher().executed(this);
// (2)
Response result = getResponseWithInterceptorChain();
// (3)
if (result == null) throw new IOException(“Canceled”);
return result;
} finally {
client.dispatcher().finished(this);
// (4)
}
}

这里我们做了 4 件事:

  1. 检查这个 call 是否已经被执行了,每个 call 只能被执行一次,如果想要一个完 全一样的 call,可以利用 call#clone 方法进行克隆。
  2. 利用 client.dispatcher().executed(this) 来进行实际执 行 dispatcher 是刚才看到的 OkHttpClient.Builder 的成员之一,它的文 档说自己是异步 HTTP 请求的执行策略,现在看来,同步请求它也有掺和。
  3. 调用 getResponseWithInterceptorChain() 函数获取 HTTP 返回结果,从 函数名可以看出,这一步还会进行一系列“拦截”操作。
  4. 最后还要通知 dispatcher 自己已经执行完毕。

dispatcher 这里我们不过度关注,在同步执行的流程中,涉及到 dispatcher 的内容 只不过是告知它我们的执行状态,比如开始执行了(调用 executed ),比如执行 完毕了(调用 finished ),在异步执行流程中它会有更多的参与。

真正发出网络请求,解析返回结果的,还 是 getResponseWithInterceptorChain

private Response getResponseWithInterceptorChain() throws IOExce ption {
// Build a full stack of interceptors.
List interceptors = new ArrayList<>();
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 (!retryAndFollowUpInterceptor.isForWebSocket()) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(
retryAndFollowUpInterceptor.isForWebSocket()));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}

InterceptorOkHttp 最核心的一个东西,不要误以为它只负责拦截请求 进行一些额外的处理(例如 cookie),实际上它把实际的网络请求、缓存、透明压 缩等功能都统一了起来,每一个功能都只是一个 Interceptor ,它们再连接成一 个 Interceptor.Chain ,环环相扣,最终圆满完成一次网络请求。

getResponseWithInterceptorChain 函数我们可以看 到 Interceptor.Chain 的分布依次是:

  1. 在配置 OkHttpClient 时设置的 interceptors
  2. 负责失败重试以及重定向的 RetryAndFollowUpInterceptor
  3. 负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换 为用户友好的响应的 BridgeInterceptor
  4. 负责读取缓存直接返回、更新缓存的 CacheInterceptor
  5. 负责和服务器建立连接的 ConnectInterceptor
  6. 配置 OkHttpClient 时设置的 networkInterceptors
  7. 负责向服务器发送请求数据、从服务器读取响应数 据 CallServerInterceptor

在这里,位置决定了功能,最后一个 Interceptor 一定是负责和服务器实际通讯的, 重定向、缓存等一定是在实际通讯之前的。 责任链模式在这个 Interceptor 链条中得到了很好的实践。

它包含了一些命令对象和一系列的处理对象,每一个处理对象决定它能处理哪 些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处 理对象。该模式还描述了往该处理链的末尾添加新的处理对象的方法。

对于把 Request 变成 Response 这件事来说,每个 Interceptor 都可能完成这 件事,所以我们循着链条让每个 Interceptor 自行决定能否完成任务以及怎么完 成任务(自力更生或者交给下一个 Interceptor )。这样一来,完成网络请求这 件事就彻底从 RealCall 类中剥离了出来,简化了各自的责任和逻辑。两个字:优 雅!

责任链模式在安卓系统中也有比较典型的实践,例如 view 系统对点击事件 (TouchEvent)的处理。

回到 OkHttp,在这里我们先简单分析一 下 ConnectInterceptorCallServerInterceptor ,看看 OkHttp 是怎么进 行和服务器的实际通信的。

2.2.1.1.建立连接: ConnectInterceptor

@Override public Response intercept(Chain chain) throws IOExcept ion {
RealInterceptorChain realChain = (RealInterceptorChain) chain;
Request request = realChain.request();
StreamAllocation streamAllocation = realChain.streamAllocation ();
// We need the network to satisfy this request. Possibly for v alidating a conditional GET. boolean doExtensiveHealthChecks = !request.method().equals(“GE T”);
HttpCodec httpCodec = streamAllocation.newStream(client, doExt ensiveHealthChecks);
RealConnection connection = streamAllocation.connection();
return realChain.proceed(request, streamAllocation, httpCodec, connection);
}

实际上建立连接就是创建了一个 HttpCodec 对象,它将在后面的步骤中被使用, 那它又是何方神圣呢?它是对 HTTP 协议操作的抽象,有两个实 现: Http1CodecHttp2Codec ,顾名思义,它们分别对应 HTTP/1.1 和 HTTP/2 版本的实现。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

小结

有了这么多优秀的开发工具,可以做出更高质量的Android应用。

当然了,“打铁还需自身硬”,想要写出优秀的代码,最重要的一点还是自身的技术水平,不然用再好的工具也不能发挥出它的全部实力。

在这里我也分享一份大佬自己收录整理的Android学习PDF+架构视频+面试文档+源码笔记,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

*,还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料这些都是我闲暇还会反复翻阅的精品资料。在脑图中,每个知识点专题都配有相对应的实战项目,可以有效的帮助大家掌握知识点。

总之也是在这里帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习

如果你有需要的话,可以点击这里领取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值