如果直到今天還有人跟你說(shuō)茉帅,不要用那些什么開(kāi)源框架,比如okhttp锭弊,不好堪澎,我們要自己寫(xiě)!
你可以反手就是一巴掌給他味滞,因?yàn)閛khttp在很久之前已經(jīng)被谷歌收錄樱蛤,谷歌已經(jīng)參照這個(gè)庫(kù)的寫(xiě)法修改了對(duì)應(yīng)的底層封裝,雖然咱們依然用的是httpurlconnection剑鞍,但其實(shí)內(nèi)部實(shí)現(xiàn)已經(jīng)被修改過(guò)了昨凡。所以簡(jiǎn)單來(lái)講,okhttp就等于源碼蚁署,下次再有人說(shuō)這種不負(fù)責(zé)的話你就往死里打便脊!
好了,我們回到正題光戈,okhttp是一個(gè)什么鬼東西我就不具體說(shuō)了哪痰,我打算把底層略淺的過(guò)一遍,一來(lái)增加自己的印象久妆,二來(lái)各位看官也可以給自己過(guò)一遍印象晌杰,我覺(jué)得看源碼就應(yīng)該只抓重點(diǎn),不然你會(huì)迷失在這片海洋里筷弦,人家一個(gè)團(tuán)隊(duì)辛辛苦苦寫(xiě)了那么久的東西肋演,你一個(gè)人怎么可能那么快能夠全盤(pán)掌握呢對(duì)吧。
估計(jì)一篇文章是不夠分析的,所以我打算分為兩篇或三篇來(lái)解析爹殊,那么話不多說(shuō)蜕乡,開(kāi)始我們的第一篇。
首先我們上個(gè)使用方式梗夸,然后我們從使用方式開(kāi)始入手一步步了解异希。
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
首先,enqueue是異步調(diào)用的方式绒瘦,同步調(diào)用是用execute称簿,他們的底層就前面有一些不一樣,后面都一樣惰帽,所以直接講異步的就行憨降。那我們先看看newCall,點(diǎn)進(jìn)去(其實(shí)不看都可以猜到他是new一個(gè)call啦~)
@Override public Call newCall(Request request) {
return new RealCall(this, request, false /* for web socket */);
}
繼續(xù)跳
RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
對(duì)吧该酗,返回了一個(gè)RealCall實(shí)例授药,保存了一些參數(shù),那么回到外面呜魄,我們看看call.enqueue()
void enqueue(Callback responseCallback);
咦悔叽,沒(méi)看到實(shí)現(xiàn),因?yàn)镽ealCall才是Call的實(shí)現(xiàn)類爵嗅,那咱們應(yīng)該去那邊看娇澎,過(guò)去查一下
@Override public void enqueue(Callback responseCallback) {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
client.dispatcher().enqueue(new AsyncCall(responseCallback));
}
誒,找到了睹晒。來(lái)趟庄,開(kāi)始一步步深入了,這里我們先去看看client.dispatcher()
public Dispatcher dispatcher() {
return dispatcher;
}
下面是這個(gè)類的開(kāi)頭伪很,有一個(gè)線索點(diǎn)
public final class Dispatcher {
private int maxRequests = 64;
private int maxRequestsPerHost = 5;
private Runnable idleCallback;
/** Executes calls. Created lazily. */
private ExecutorService executorService;
...
看到ExecutorService了戚啥,其實(shí)Dispatcher就是一個(gè)線程分發(fā)器,用來(lái)處理請(qǐng)求線程的锉试,利用線程池類去維護(hù)猫十。那我們繼續(xù),回到上面去看看dispatcher().enqueue()
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
首先把自己添加進(jìn)了隊(duì)列呆盖,然后調(diào)用了線程池的execute方法拖云,ok完成它的使命了,那咱們繼續(xù)回到前面絮短,看看最后的enqueue(new AsyncCall(responseCallback))的AsyncCall是個(gè)什么鬼
final class AsyncCall extends NamedRunnable {
窩江兢,是個(gè)線程(這TM不是廢話嗎!)丁频,那我們來(lái)找找它的Run方法,咦,沒(méi)有席里,那就去父類看看
public abstract class NamedRunnable implements Runnable {
protected final String name;
public NamedRunnable(String format, Object... args) {
this.name = Util.format(format, args);
}
@Override public final void run() {
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(name);
try {
execute();
} finally {
Thread.currentThread().setName(oldName);
}
}
protected abstract void execute();
}
在這里了叔磷,調(diào)用了execute()方法,然而是個(gè)抽象方法奖磁,那就去他子類找這個(gè)方法的實(shí)現(xiàn)
@Override protected void execute() {
boolean signalledCallback = false;
try {
Response response = getResponseWithInterceptorChain();
if (retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
} else {
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);
}
} finally {
client.dispatcher().finished(this);
}
}
兄弟們改基,execute()這個(gè)方法名是不是有點(diǎn)熟悉?
對(duì)的咖为,如果我們一開(kāi)始用同步秕狰,那么會(huì)直接跑到這里來(lái)。
所以說(shuō)這兩個(gè)方法后面從這里開(kāi)始都是一樣的了躁染,前面就是上面講的那些不一樣鸣哀,多了個(gè)線程池。
好吞彤,接下來(lái)要深入的是getResponseWithInterceptorChain我衬,走起
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of 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));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
要開(kāi)始繼續(xù)深入了,可以這樣講饰恕,okhttp的核心之一就是這一堆的攔截器挠羔。但是咱們先剎個(gè)車,先來(lái)回顧一下剛剛走的流程:
1埋嵌,我們使用okHttpClient.newCall實(shí)例出了Call的實(shí)現(xiàn)類
2破加,我們調(diào)用了它的異步方法 ,里面重點(diǎn)是client.dispatcher().enqueue(new AsyncCall(responseCallback))
3雹嗦,其中Dispatcher是這里面的分發(fā)器拌喉,它內(nèi)部使用了ExecutorService線程池,然后將我們的AsyncCall添加了進(jìn)去
4俐银,我們的AsyncCall實(shí)現(xiàn)了Runnable尿背,在run方法里執(zhí)行了execute(),這也是一開(kāi)始調(diào)用同步方法后走的地方
5捶惜,execute()方法注冊(cè)了一系列攔截器田藐,并組成了責(zé)任鏈(劃重點(diǎn),責(zé)任鏈設(shè)計(jì)模式吱七,Okhttp的核心)
ok汽久,這一篇先到這過(guò),下一篇咱們從責(zé)任鏈這里開(kāi)始踊餐。
Android-OKHttp底層原理淺析(二)