一、OkHttp源码解析
(1)client = new OkHttpClient():初始化OkHttpClient
public OkHttpClient() {
this(new 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;
}
(2)new Request.Builder().addHeader("token", token).url(url).post(builder.build()).build():网络请求配置参数
public Builder() {
this.method = "GET";//默认为get请求
this.headers = new Headers.Builder();
}
//保存头部信息
public Builder addHeader(String name, String value) {
headers.add(name, value);
return this;
}
//请求连接
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));
}
//设置请求方式
public Builder post(RequestBody body) {
return method("POST", body);
}
//创建Request实例,赋值设置需求
public Request build() {
if (url == null) throw new IllegalStateException("url == null");
return new Request(this);
}
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);
}
(3)client.newCall(request).enqueue(callback):封装Call对象异步请求
@Override
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
RealCall call = new RealCall(client, originalRequest, forWebSocket);
call.transmitter = new Transmitter(client, call);
return call;
}
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
}
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);
}
@Override
public void enqueue(Callback responseCallback) {
//使用synchronized防止请求重复执行
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
transmitter.callStart();//调用监听方法
//AsyncCall继承NamedRunnable抽象类,NamedRunnable实现Runnable,调用执行run方法
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
AsyncCall(Callback responseCallback) {
super("OkHttp %s", redactedUrl());
this.responseCallback = responseCallback;
}
@Override
protected void execute() {
boolean signalledCallback = false;
transmitter.timeoutEnter();
try {
//返回数据
Response response = getResponseWithInterceptorChain();
signalledCallback = true;
//成功回调
responseCallback.onResponse(RealCall.this, response);
} catch (IOException e) {
if (signalledCallback) {
// Do not signal the callback twice!
Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
} else {
//失败异常回调
responseCallback.onFailure(RealCall.this, e);
}
} catch (Throwable t) {
cancel();
if (!signalledCallback) {
IOException canceledException = new IOException("canceled due to " + t);
canceledException.addSuppressed(t);
//失败异常回调
responseCallback.onFailure(RealCall.this, canceledException);
}
throw t;
} finally {
//清除队列
client.dispatcher().finished(this);
}
}
- OkHttpClient:是OkHttp框架的客户端。用户使用OkHttp进行各种设置,发起各种网络请求都是通过OkHttpClient完成的。每个OkHttpClient内部都维护了属于自己的任务队列,连接池,Cache,拦截器等,所以在使用OkHttp作为网络框架时应该全局共享一个OkHttpClient实例。
- Call:Call是描述一个实际的访问请求,用户的每一个网络请求都是一个Call实例。Call本身只是一个接口,定义了Call的接口方法,实际执行过程中,OkHttp会为每一个请求创建一个RealCall,每一个RealCall内部有一个AsyncCall,AsyncCall是RealCall的一个内部类并且继承NamedRunnable。
- Dispatcher:OkHttp的任务队列,其内部维护了一个线程池,当有接收到一个Call时,Dispatcher负责在线程池中找到空闲的线程并执行其execute方法。