看一下Okhttp原始碼

2021-08-19 22:13:13 字數 4629 閱讀 4642

看一下okhttp原始碼,學習一下框架的原理,加深對網路請求的理解。做一下筆記。

//獲取okhttpclient,一般應用只有乙個,便於共享response快取,執行緒池,復用連線

public call newcall(request request)

進入realcall(),實際上同步請求呼叫的是realcall的execute(),非同步請求呼叫的是realcall()的enqueue()

先看同步請求:

雖然說dispatcher主要用於併發的任務排程,相當於乙個範發起,但是同時它也可以做同步的請求操作。在同步中,dispatch只是告訴我們狀態,當要呼叫時就呼叫execute(),當要完成了就執行finish()。首先我們做乙個同步判斷,判斷call是否已經被同步請求了,因為同步的call只能被執行一次,如果要執行多次可以呼叫call.clone()。然後我們通過getresponsewithinterceptorchain(false);去獲取response,最精髓的也就是***的作用了,它整合了很多操作。

@override

public response execute() throws ioexception

try finally

}

在finish中也就是將佇列中的請求清空而已。

/** used by  to signal completion. */

synchronized

void finished(asynccall call)

再看非同步請求,我們重點看一下***和dispatch

void enqueue(callback responsecallback, boolean forwebsocket) 

client.dispatcher().enqueue(new asynccall(responsecallback, forwebsocket));

}

進入dispatcher().enqueue()方法,

synchronized void enqueue(asynccall call)  else 

}

我們應當來看三個佇列分別是什麼

//正在準備的非同步請求a

private

final dequereadyasynccalls = new arraydeque<>();

//正在執行的非同步請求b

private

final dequerunningasynccalls = new arraydeque<>();

//正在執行的同步請求c

private

final dequerunningsynccalls = new arraydeque<>();

當b的數量<64並且正在執行的主機數<5時,把請求放在b中執行;否則就加到a中進行快取等待

看一下finished()中的方法:它會從佇列a中取出乙個請求加到b中。

private

void

promotecalls()

if (runningasynccalls.size() >= maxrequests) return; // reached max capacity.

}}

看一下dispatch對執行緒池的使用,我們可以選擇自己設定執行緒池,可以執行大量耗時的任務。在dispatch的enqueue()中,當正在執行的非同步佇列中加入runningasynccalls的時候,我們的執行緒池方法就會被呼叫executorservice().execute(call);,在後台執行,最終會去呼叫***,這裡只是對執行緒池做了乙個封裝而已。

public

dispatcher(executorservice executorservice)

public

dispatcher()

public

synchronized executorservice executorservice()

return executorservice;

}

再看***

retryandfollowupinterceptor 重定向當另外乙個url失敗時

bridgeinterceptor 橋接 使用者構造的請求轉化為傳送給伺服器的請求,把伺服器返回的response傳給使用者進行友好的輸出響應

cacheinterceptor 讀取更新快取

connectioninteceptor與伺服器連線的***

callserverinteceptor 網路伺服器的連線

}}其中的getresponse()主要呼叫了httpengine中的engine.sendrequest();

engine.readresponse();它主要是處理單個http請求和響應對。http都遵循這個生命週期:當傳送請求而訊息時就呼叫sendmessage(),此時不能修改請求頭,當上一次的快取可以使用的時候就直接使用快取。當接收響應的時候,呼叫readresponse(),當快取存在就直接用快取並且更新快取,否則使用網路請求的資料。所有響應都有乙個響應體輸入流,不過在某些情況下,該流是空的。

檢查快取是否有效:通過響應頭的字段last-modified返回的date值去判斷

private

static

boolean

validate(response cached, response network)

date lastmodified = cached.headers().getdate("last-modified");

if (lastmodified != null)

}return

false;

}

我們的失敗重連也是通過httpengine的recover來實現的,所以說它的功能非常強大

OkHttp原始碼解析 一

執行請求的地方.client.newcall request enqueue new callback override public void onresponse call call,response response throws ioexception okhttpclient的newcal...

OkHttp 原始碼分析(一)

首先我們來看一段 我們直接來看這一段 研究okhttpclient這個類之前,我們先來看看他都實現了那些類。這裡我們就很明白newcall 的來歷了。廢話不多說直接看okhttpclient的newcall方法。public class okhttpclient implements cloneab...

進來看一下

進來看下,知道的解答一下,實在是不明白.聽君一席話,勝讀十年書!include include using namespace std string fun1 const string s1,const string s2 const string fun2 string s1,const stri...