OkHttp3.6.0源码解析
2018-07-06 本文已影响56人
Wocus
前言
OkHttp是一个非常流行的框架,已经被谷歌加入开源库中,Retrofit目前也是采用OkHttp实现的,此文章纯属个人笔记。
github地址 https://github.com/square/okhttp
基本使用
val httpClient=OkHttpClient()
val request=Request.Builder().url("www.baidu.com").build()
//同步请求
val response= httpClient.newCall(request).execute()
if(response.isSuccessful)
"成功"
else
"失败"
//异步请求
httpClient.newCall(request).enqueue(object :Callback{
override fun onFailure(call: Call?, e: IOException?) {
}
override fun onResponse(call: Call?, response: Response?) {
}
})
1.实例化OkHttpClient()
2.初始化请求头request
3.带上请求头发送请求,回掉
源码解析
一,HttpClient()
public OkHttpClient() {
this(new 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;
pingInterval = 0;
}
初始化OkhttpClient里面初始化了很多值
二,Request
final HttpUrl url;//请求地址
final String method;//请求方式
final Headers headers;//请求头
final RequestBody body;//请求内容
final Object tag;
public Builder() {
this.method = "GET";
this.headers = new Headers.Builder();
}
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);
}
HttpUrl parsed = HttpUrl.parse(url);
if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
return url(parsed);
}
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
public Builder get() {
return method("GET", null);
}
public Builder post(RequestBody body) {
return method("POST", body);
}
此代码非常的清楚
1.Builder()默认请求get,初始化请求头
2.url(string)url赋值,在里面并且判断url是否为空拼接完整htpp请求网址,最后判断此http请求是否可用并返回
3.build()初始化完成
三,Response
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
}
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
如果executed等于true,说明已经被执行,如果再次调用执行就抛出异常。这说明了一个Call只能被执行。
可以看到同步请求生成的是RealCall对象,而异步请求生成的是AsyncCall对象。AsyncCall说到底其实就是Runnable的子类。
接着上面继续分析,如果可以执行,则对当前请求添加监听器等操作,然后将请求Call对象放入调度器Dispatcher中。最后由拦截器链中的各个拦截器来对该请求进行处理,返回最终的Response。