OkHttp官网地址:https://square.github.io/okhttp/
用法如下:(get请求)
package okhttp3.guide;import java.io.IOException;import okhttp3.OkHttpClient;import okhttp3.Request;import okhttp3.Response;public class GetExample {OkHttpClient client = new OkHttpClient();String run(String url) throws IOException {Request request = new Request.Builder().url(url).build();try (Response response = client.newCall(request).execute()) {return response.body().string();}}public static void main(String[] args) throws IOException {GetExample example = new GetExample();String response = example.run("https://raw.github.com/square/okhttp/master/README.md");System.out.println(response);}}
Github下载源码地址https://github.com/square/okhttp
4.x以上的版本都大部分更新为kotlin了,可以更改分支下载3.x的版本来看
一。先来看第一步构造函数
OkHttpClient client = new OkHttpClient();
源码:
public OkHttpClient() {this(new Builder());}
Builder()中就是初始化了一堆变量,没啥东西
二。来看get请求
new Request.Builder()
源码:找内部类Builder的构造函数
public Builder() {this.method = "GET";this.headers = new Headers.Builder();}
源码:接着找Headers的内部类Builder,暂时构造了一个变量,还没有做什么
三。下面是执行.url方法,当然是Request内部类Builder的url方法,url暂定为String
源码:
public Builder url(String url) {if (url == null) throw new NullPointerException("url == null");// Silently replace web socket URLs with HTTP URLs.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));}
前面是加前缀,后面去到HttpUrl里去
public static HttpUrl get(String url) {return new Builder().parse(null, url).build();}
HttpUrl的内部类Builder的构造函数
public Builder() {encodedPathSegments.add(""); // The default path is '/' which needs a trailing space.}
encodedPathSegments是一个ArrayList
HttpUrl的内部类Builder的parse方法就是一连串的参数解析,大家可以看源码
最后一个build()方法
public HttpUrl build() {if (scheme == null) throw new IllegalStateException("scheme == null");if (host == null) throw new IllegalStateException("host == null");return new HttpUrl(this);}
这个HttpUrl的带参构造函数中也是一堆变量的初始化
回到Request内部类Builder的url方法
public Builder url(HttpUrl url) {if (url == null) throw new NullPointerException("url == null");this.url = url;return this;}
接着是Request内部类Builder的build方法
public Request build() {if (url == null) throw new IllegalStateException("url == null");return new Request(this);}
Request的带参构造函数
Request(Builder builder) {this.url = builder.url;this.method = builder.method;this.headers = builder.headers.build();this.body = builder.body;this.tags = Util.immutableMap(builder.tags);}
四。接下来很重要了,是执行请求
Response response = client.newCall(request).execute()
OkHttpClient中的newCall方法
@Override public Call newCall(Request request) {return RealCall.newRealCall(this, request, false /* for web socket */);}
进到RealCall中的newRealCall方法
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {// Safely publish the Call instance to the EventListener.RealCall call = new RealCall(client, originalRequest, forWebSocket);call.transmitter = new Transmitter(client, call);return call;}
构造函数不用管,进去Transmitter中的构造函数
public Transmitter(OkHttpClient client, Call call) {this.client = client;this.connectionPool = Internal.instance.realConnectionPool(client.connectionPool());this.call = call;this.eventListener = client.eventListenerFactory().create(call);this.timeout.timeout(client.callTimeoutMillis(), MILLISECONDS);}
其中这个Internal.instance.realConnectionPool(client.connectionPool())可以找到OkHttpClient的static代码块执行后返回了一个RealConnectionPool
private static final Executor executor = new ThreadPoolExecutor(0 /* corePoolSize */,Integer.MAX_VALUE /* maximumPoolSize */, 60L /* keepAliveTime */, TimeUnit.SECONDS,new SynchronousQueue<>(), Util.threadFactory("OkHttp ConnectionPool", true));
RealConnectionPool一看就知道是0个核心线程,最大值个非核心线程的线程池;这里还出现了一个Deque双端队列,即队列的升级版,两个端口都可以进出元素,更加灵活
最后就是RealCall的execute方法了,注意RealCall里有个内部类AsyncCall也有execute方法,注意不要搞混了
@Override public Response execute() throws IOException {synchronized (this) {if (executed) throw new IllegalStateException("Already Executed");executed = true;}transmitter.timeoutEnter();transmitter.callStart();try {client.dispatcher().executed(this);return getResponseWithInterceptorChain();} finally {client.dispatcher().finished(this);}}
client.dispatcher().executed(this)执行的是
synchronized void executed(RealCall call) {runningSyncCalls.add(call);}
runningSyncCalls就是我们上面提到的Deque双端队列
下面就是最最核心的getResponseWithInterceptorChain方法
Response getResponseWithInterceptorChain() throws IOException {// Build a full stack of interceptors.List<Interceptor> 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);}}}
RetryAndFollowUpInterceptor重试和跳转拦截器
BridgeInterceptor桥接拦截器,即加请求头和去响应头
CacheInterceptor缓存拦截器
ConnectInterceptor连接拦截器
CallServerInterceptor调用服务拦截器
List添加好全部Interceptor之后,执行chain.proceed(originalRequest)来到RealInterceptorChain中的proceed方法
public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)throws IOException {if (index >= interceptors.size()) throw new AssertionError();calls++;// If we already have a stream, confirm that the incoming request will use it.if (this.exchange != null && !this.exchange.connection().supportsUrl(request.url())) {throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)+ " must retain the same host and port");}// If we already have a stream, confirm that this is the only call to chain.proceed().if (this.exchange != null && calls > 1) {throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)+ " must call proceed() exactly once");}// Call the next interceptor in the chain.RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,index + 1, request, call, connectTimeout, readTimeout, writeTimeout);Interceptor interceptor = interceptors.get(index);Response response = interceptor.intercept(next);// Confirm that the next interceptor made its required call to chain.proceed().if (exchange != null && index + 1 < interceptors.size() && next.calls != 1) {throw new IllegalStateException("network interceptor " + interceptor+ " must call proceed() exactly once");}// Confirm that the intercepted response isn't null.if (response == null) {throw new NullPointerException("interceptor " + interceptor + " returned null");}if (response.body() == null) {throw new IllegalStateException("interceptor " + interceptor + " returned a response with no body");}return response;}
Interceptor interceptor = interceptors.get(index);Response response = interceptor.intercept(next);
一开始传入的index为0,就是从第一个拦截器开始执行每个拦截器的intercept方法,index逐次+1
每个拦截器里都调用chain.proceed,这样所有的拦截器就形成链条。这里每个拦截器的作用就不讲了
欢迎关注我的微信公众号:安卓圈





