前言
OkHttp是目前很流行的網(wǎng)絡(luò)請(qǐng)求框架。源碼也設(shè)計(jì)很優(yōu)秀的思想。有必要去探究一下源碼。
由于篇幅較長(zhǎng),分為五篇文章。本篇文章將討論OkHttp的執(zhí)行流程分析
文章目錄
一、OkHttp執(zhí)行流程分析
二、同步請(qǐng)求流程分析
三、異步請(qǐng)求流程分析
四、任務(wù)調(diào)度核心dispatcher
五、OkHttp中五大攔截器源碼與功能分析
OkHttp執(zhí)行流程分析
流程圖
流程分析
1、創(chuàng)建OkHttpClient
OkHttpClient是一個(gè)通過(guò)build模式去構(gòu)建的。
public Builder() {
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
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;
}
然后通過(guò)build的build方法構(gòu)建
public OkHttpClient build() {
return new OkHttpClient(this);
}
這里主要是通過(guò)build設(shè)計(jì)模式配置一些常用的參數(shù)信息,如超時(shí)時(shí)間等。
2、創(chuàng)建Request
public Builder() {
this.method = "GET";
this.headers = new Headers.Builder();
}
Builder(Request request) {
this.url = request.url;
this.method = request.method;
this.body = request.body;
this.tag = request.tag;
this.headers = request.headers.newBuilder();
}
Request也是通過(guò)build模式配置一些請(qǐng)求信息等,如url,請(qǐng)求方法,請(qǐng)求體,請(qǐng)求頭等。
3、創(chuàng)建Call
Call call = client.newCall(request);
主要是通過(guò)client.newCall然后傳入一個(gè)request來(lái)進(jìn)行創(chuàng)建。
@Override
public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false);
}
這里其實(shí)是創(chuàng)建了一個(gè)RealCall,RealCall也是OkHttp框架主要流程的一部分,主要是鏈接request和Response的橋梁,通過(guò)call進(jìn)行同步和異步方法的執(zhí)行。在同步和異步的執(zhí)行方法里會(huì)返回response。例如:
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
4、通過(guò)Call執(zhí)行同步或者異步請(qǐng)求,獲取response
Response response = call.execute();
System.out.println(response.body().string());
上面已經(jīng)說(shuō)過(guò)通過(guò)call的execute可以進(jìn)行同步請(qǐng)求,然后獲取response,這個(gè)response就是我們想要的返回的信息。
也可以通過(guò)call.enqueue方法傳入也一個(gè)監(jiān)聽(tīng)器,進(jìn)行異步請(qǐng)求。
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//返回失敗的情況
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//調(diào)用成功的情況
}
});
5、完整的get請(qǐng)求,和post請(qǐng)求示例
get
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
post
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
6、總結(jié)
這篇只是簡(jiǎn)單分析OkHttp的使用流程,其實(shí)還有一部分核心的流程是在源碼中體現(xiàn)的比如dispatcher調(diào)度器的使用流程,與攔截器的核心功能等,這一部分將在后面的總結(jié)中進(jìn)行單獨(dú)分析。