android開發(fā)中大部分的網(wǎng)絡(luò)框架都用到了okhttp,okhttp既HTTP框架缨叫,今天通過代碼理清一下okhttp的運行思路着降,先看一段代碼
String url = "http://www.baidu.com";
?OkHttpClient client = new OkHttpClient();
?new OkHttpClient().newBuilder();
?Request request = new Request.Builder()
?.url(url)
? .get()? //默認(rèn)為GET請求硝枉,可以不寫
? .build();
? final Call call = client.newCall(request);
? ? ? ? try {
? ? ? ? ? ? call.execute();? ? ? //同步
? ? ? ? ? ? call.enqueue(new Callback() {? //異步
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public void onFailure(Call call, IOException e) {
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public void onResponse(Call call, Response response) throws IOException {
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? ? ? call.cancel();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
這里先看OkHttpClient client = new OkHttpClient();中的OkHttpClient
第一步就是創(chuàng)建okhttpclient對象
第二步創(chuàng)建請求對象
Request request = new Request.Builder()
?.url(url)
? .get()? //默認(rèn)為GET請求烁登,可以不寫
? .build();
經(jīng)過這幾步完成了request的數(shù)據(jù)賦值
ok,現(xiàn)在要進行網(wǎng)絡(luò)請求
?final Call call = client.newCall(request);
網(wǎng)絡(luò)請求分同步和異步兩種
同步?call.execute();
先看client.dispatcher().executed(this);
executed執(zhí)行的時候會把call回調(diào)對象裝到runningSyncCalls集合中
/** Running synchronous calls. Includes canceled calls that haven't finished yet. */
private final DequerunningSyncCalls =new ArrayDeque<>();
異步call.enqueue(new Callback() {//異步
? ? ? ? ? @Override
? ? ? ? ? public void onFailure(Call call, IOException e) {
? ? ? ? ? ?}
? ? ? ? ?@Override
? ? ? ? ?public void onResponse(Call call, Response response)throws IOException {
}
});
攔截器是 OkHttp 提供的對 Http 請求和響應(yīng)進行統(tǒng)一處理的強大機制,它可以實現(xiàn)網(wǎng)絡(luò)監(jiān)聽钞馁、請求以及響應(yīng)重寫虑省、請求失敗充實等功能
chain.proceed():方法是 Http 開始工作的地方匿刮,就是由它產(chǎn)生了與請求相對應(yīng)的響應(yīng)。
攔截器的分類:Application Interceptor(應(yīng)用攔截器)和?NetWork Interceptor(網(wǎng)絡(luò)攔截器)
? ?1.應(yīng)用攔截器
? ? (1)不能操作中間的響應(yīng)結(jié)果探颈,比如重定向和重試熟丸,只能操作客戶端主動的第一次請求以及最終的響應(yīng)結(jié)果。
? ? (2)始終調(diào)用一次膝擂,即使Http響應(yīng)是從緩存中提供的虑啤。
? ? (3)關(guān)注原始的request,而不關(guān)心注入的headers架馋,比如If-None-Match狞山。
? ? (4)允許短路 short-circuit ,并且不調(diào)用 chain.proceed()叉寂。(注:這句話的意思是Chain.proceed()不需要一定要獲取來自服務(wù)器的響應(yīng)萍启,但是必須還是需要返回Respond實例。那么實例從哪里來屏鳍?答案是緩存勘纯。如果本地有緩存,可以從本地緩存中獲取響應(yīng)實例返回給客戶端钓瞭。這就是short-circuit (短路)的意思)
? ? (5)允許請求失敗重試驳遵,并多次調(diào)用 chain.proceed();
? 2.網(wǎng)絡(luò)攔截器
? ? (1)能夠?qū)χ囟ㄏ蚝椭卦嚨戎虚g響應(yīng)進行操作
? ? (2)不允許調(diào)用緩存來short-circuit (短路)這個請求。(注:意思就是說不能從緩存池中獲取緩存對象返回給客戶端山涡,必須通過請求服務(wù)的方式獲取響應(yīng)堤结,也就是Chain.proceed())
? ? (3)觀察網(wǎng)絡(luò)傳輸中數(shù)據(jù)傳輸和變化(注:比如當(dāng)發(fā)生了重定向時,我們就能通過網(wǎng)絡(luò)攔截器來確定存在重定向的情況)
? ? (4)可以獲取 Connection 攜帶的請求信息(即可以通過chain.connection() 獲取非空對象)