OkHttp 3 7原始碼分析(一) 整體架構

2021-09-23 18:06:44 字數 3276 閱讀 6117

okhttp3.7原始碼分析文章列表如下:

okhttp是乙個處理網路請求的開源專案,是android端最火熱的輕量級框架,由移動支付square公司貢獻用於替代httpurlconnection和apache httpclient。隨著okhttp的不斷成熟,越來越多的android開發者使用okhttp作為網路框架。

之所以可以贏得如此多開發者的喜愛,主要得益於如下特點:

為了一探okhttp是如何具備以下特點的,筆者反覆研究okhttp框架原始碼,力求通過原始碼分析向各位解釋一二。所以特意準備了幾篇部落格跟大家一起**下okhttp的方方面面,今天首先從整體架構上分析下okhttp。

首先來看下okhttp的簡單使用,okhttp提供了兩種呼叫方式:

同步呼叫

@override public response execute() throws ioexception 

try finally

}

首先加鎖置標誌位,接著使用分配器的executed方法將call加入到同步佇列中,然後呼叫getresponsewithinterceptorchain方法(稍後分析)執行http請求,最後呼叫finishied方法將call從同步佇列中刪除

非同步請求

void enqueue(callback responsecallback, boolean forwebsocket) 

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

}

同樣先置標誌位,然後將封裝的乙個執行體放到非同步執行佇列中。這裡面引入了乙個新的類asynccall,這個類繼承於namedrunnable,實現了runnable介面。namedrunnable可以給當前的執行緒設定名字,並且用模板方法將執行緒的執行體放到了execute方法中

***除了同步呼叫和非同步呼叫,okhttp還提供了乙個***的概念。***提供了攔截請求和攔截伺服器應答的介面。okhttp提供了乙個***鏈的概念,通過將乙個個***組合成乙個***鏈,可以達到在不同層面做不同攔截操作的效果,有點aop的意思。具體***的使用可以參考:okhttp-wiki 之 interceptors ***

上圖是okhttp的總體架構,大致可以分為以下幾層:

inte***ce——介面層:

介面層接收使用者的網路訪問請求(同步請求/非同步請求),發起實際的網路訪問。okhttpclient是okhttp框架的客戶端,更確切的說是乙個使用者面板。使用者使用okhttp進行各種設定,發起各種網路請求都是通過okhttpclient完成的。每個okhttpclient內部都維護了屬於自己的任務佇列,連線池,cache,***等,所以在使用okhttp作為網路框架時應該全域性共享乙個okhttpclient例項。

call描述乙個實際的訪問請求,使用者的每乙個網路請求都是乙個call例項。call本身只是乙個介面,定義了call的介面方法,實際執行過程中,okhttp會為每乙個請求建立乙個realcall,每乙個realcall內部有乙個asynccall:

final class asynccall extends namedrunnable 

string host()

request request()

realcall get()

@override protected void execute()

...}

asynccall繼承的namedrunnable繼承自runnable介面:

public abstract class namedrunnable implements runnable 

@override public final void run() finally

} protected abstract void execute();

}

所以每乙個call就是乙個執行緒,而執行call的過程就是執行其execute方法的過程。

protocol——協議層:處理協議邏輯

protocol層負責處理協議邏輯,okhttp支援http1/http2/websocket協議,並在3.7版本中放棄了對spdy協議,鼓勵開發者使用http/2。

connection——連線層:管理網路連線,傳送新的請求,接收伺服器訪問

連線層顧名思義就是負責網路連線。在連線層中有乙個連線池,統一管理所有的socket連線,當使用者新發起乙個網路請求時,okhttp會首先從連線池中查詢是否有符合要求的連線,如果有則直接通過該連線傳送網路請求;否則新建立乙個網路連線。

realconnection描述乙個物理socket連線,連線池中維護多個realconnection例項。由於http/2支援多路復用,乙個realconnection可以支援多個網路訪問請求,所以okhttp又引入了streamallocation來描述乙個實際的網路請求開銷(從邏輯上乙個stream對應乙個call,但在實際網路請求過程中乙個call常常涉及到多次請求。如重定向,authenticate等場景。所以準確地說,乙個stream對應一次請求,而乙個call對應一組有邏輯關聯的stream),乙個realconnection對應乙個或多個streamallocation,所以streamallocation可以看做是realconenction的計數器,當realconnection的引用計數變為0,且長時間沒有被其他請求重新占用就將被釋放。

cache——快取層:管理本地快取

i/o——i/o層:實際資料讀寫實現

i/o層負責實際的資料讀寫。okhttp的另一大有點就是其高效的i/o操作,這歸因於其高效的i/o庫okio

inteceptor——***層:攔截網路訪問,插入攔截邏輯

OkHttp 原始碼分析(一)

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

OkHttp 原始碼分析

先來看 new okhttpclient 然後 clien.newcall request 建立了 realcall 物件,這也是 okhttp 中乙個重要的類,先來分析非同步執行的原始碼吧,因為同步執行跟非同步的後半段沒什麼區別了。override public void enqueue call...

OkHttp原始碼分析(四)DiskLruCache

前一章講到okhttp使用的快取是disklrucache,displrucache是以linkedhashmap為底層實現的磁碟快取,但是具體是如何快取的我還是不是很理解,作為程式設計師,不理解和鹹魚有什麼分別。為了不做鹹魚,我們還是看一下原始碼吧!public final class diskl...