目录
前言
接上文网络请求框架OkHttp的同步异步简单使用介绍《》,今天就对同步请求的源码分析一下,加深一下印象。记录一下,方便自己查阅。
正文
这里用的框架版本
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
有新版本,我没有升级,暂时就以这个记录。
下面是同步代码
//创建OkHttpClient OkHttpClient client = new OkHttpClient.Builder().build(); //创建Request Request request = new Request.Builder().get().url("https://www.biumall.com/").build(); //创建Call,其实也是对request的封装 Call call = client.newCall(request); //同步请求 Response response = call.execute();
OkHttpClient
OkHttpClient的创建是用了Builder模式。进入Builder()
Builder()
public Builder() { dispatcher = new Dispatcher(); protocols = DEFAULT_PROTOCOLS; connectionSpecs = DEFAULT_CONNECTION_SPECS; eventListenerFactory = EventListener.factory(EventListener.NONE); proxySelector = ProxySelector.getDefault(); if (proxySelector == null) { proxySelector = new NullProxySelector(); } 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; callTimeout = 0; connectTimeout = 10_000; readTimeout = 10_000; writeTimeout = 10_000; pingInterval = 0; }
也就是参数的初始化
Request
也是用了Builder模式,初始化请求方式和添加url。
Builder()
public Builder() { this.method = "GET"; this.headers = new Headers.Builder(); }
请求方式可以用默认的,也可以进行修改。
public Builder get() { return method("GET", null); } public Builder post(RequestBody body) { return method("POST", body); } public Builder delete(@Nullable RequestBody body) { return method("DELETE", body); } public Builder put(RequestBody body) { return method("PUT", body); } public Builder patch(RequestBody body) { return method("PATCH", body); }
url()
传入请求url
public Builder url(String url) { if (url == null) throw new NullPointerException("url == null"); if (url.regionMatches(true, 0, "ws:", 0, 3)) { url = "http:" + url.substring(3); } else if (url.regionMatches(true, 0, "wss:", 0, 4)) { url = "https:" + url.substring(4); } return url(HttpUrl.get(url)); }
进行null判断和一定规则转换
public Builder url(HttpUrl url) { if (url == null) throw new NullPointerException("url == null"); this.url = url; return this; }
最终传入到Request的url中。
Call
# OkHttpClient.java @Override public Call newCall(Request request) { return RealCall.newRealCall(this, request, false); }
真正调用的是RealCall的newRealCall()
newRealCall()
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) { //创建RealCall RealCall call = new RealCall(client, originalRequest, forWebSocket); //初始化eventListener call.eventListener = client.eventListenerFactory().create(call); return call; }
这里创建了RealCall对象
RealCall
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) { this.client = client; this.originalRequest = originalRequest; this.forWebSocket = forWebSocket; this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket); this.timeout = new AsyncTimeout() { @Override protected void timedOut() { cancel(); } }; this.timeout.timeout(client.callTimeoutMillis(), MILLISECONDS); }
execute()
同步请求。Call中没有实现,在RealCall中实现了,而且上面创建并返回的就是RealCall对象。
# RealCall.java @Override public Response execute() throws IOException { synchronized (this) { //是否执行过标志,如果已经请求过,就不能再次请求了 if (executed) throw new IllegalStateException("Already Executed"); executed = true; } captureCallStackTrace(); timeout.enter(); eventListener.callStart(this); try { //同步请求 client.dispatcher().executed(this); //获取Response Response result = getResponseWithInterceptorChain(); if (result == null) throw new IOException("Canceled"); return result; } catch (IOException e) { e = timeoutExit(e); eventListener.callFailed(this, e); throw e; } finally { //通知请求结束 client.dispatcher().finished(this); } }
上面有备注,我们看重点
client.dispatcher().executed(this);
executed()
调用的是Dispatcher的,很简单,也就是添加到同步任务列表中。
synchronized void executed(RealCall call) { runningSyncCalls.add(call); }
getResponseWithInterceptorChain()
拦截链创建,这次才是真正的网络请求。
Response getResponseWithInterceptorChain() throws IOException { // 创建需要的拦截器,并添加到interceptors List<Interceptor> 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 (!forWebSocket) { interceptors.addAll(client.networkInterceptors()); } interceptors.add(new CallServerInterceptor(forWebSocket)); //创建RealInterceptorChain拦截器链 //也就是把上面拦截器进行链接在一起,一级一级的调用,返回Response Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest, this, eventListener, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis()); return chain.proceed(originalRequest); }
下面是主要的拦截器
RetryAndFollowUpInterceptor BridgeInterceptor CacheInterceptor ConnectInterceptor CallServerInterceptor
进入proceed,这里是会把所有的拦截器串在一起。
# RealInterceptorChain.java @Override public Response proceed(Request request) throws IOException { return proceed(request, streamAllocation, httpCodec, connection); }
真正处理是这里
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, RealConnection connection) throws IOException { //略 //[重点],获取下一个拦截器链(index + 1),也就是第一个不处理 RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, writeTimeout); //获取list中的拦截器 Interceptor interceptor = interceptors.get(index); //[重点]调用拦截器的intercept() Response response = interceptor.intercept(next); //略 return response; }
关注
Response response = interceptor.intercept(next);
interceptor就是我们上面存在interceptors中的拦截器。第一个不处理,也就是上面访问第二个RetryAndFollowUpInterceptor。
因此上面等于
RetryAndFollowUpInterceptor.intercept(next)
这里只是简单介绍,细节不介绍哈,目前关注就是如何串在一起的。
# RetryAndFollowUpInterceptor.java @Override public Response intercept(Chain chain) throws IOException { while (true) { //略 Response response; boolean releaseConnection = true; try { //[重点]又调用了proceed(),是不是又回到上面了,index+1 //response是下一个拦截器返回的。 response = realChain.proceed(request, streamAllocation, null, null); releaseConnection = false; } catch (RouteException e) { } catch (IOException e) { } finally { } } }
proceed()中的index+1,那就是再一次执行下一个拦截器。
类似于递归,只是每次调用的拦截器不一样,直到遍历完interceptors。
finished
void finished(RealCall call) { finished(runningSyncCalls, call); }
private <T> void finished(Deque<T> calls, T call) { Runnable idleCallback; synchronized (this) { if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!"); idleCallback = this.idleCallback; } boolean isRunning = promoteAndExecute(); if (!isRunning && idleCallback != null) { idleCallback.run(); } }
参考文章
《
© 版权声明