這兩天花時間看了下Volley的源碼,參考了幾篇博文 Android Volley完全解析(四),帶你從源碼的角度了解Volley,Volley 源碼解析,谷歌Volley網絡架構講解——網絡樞紐等,有一點自己小小的心得體會,在此寫出來和大家分析。
1.基本網絡請求操作封裝
既然是網絡架構,最重要的當是網絡請求相關操作的處理,在沒有網絡請求架構的時候,我們是利用最基本的HttpClient和HttpURLConnection進行網絡請求的。
先看一張Volley主要網絡請求類——HttpClientStack, HurlStack ,BasicNetwork,Volley等的UML結構圖(取自谷歌Volley網絡架構講解——網絡樞紐):
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZwpmLzYjY2U2MjRWYjVGZhVDNhRGN0QDMzcjN5IzMxQWO1UWLxIDO1ETMwMzLchDMzEDMy8CX5gjM3AzMvw1ZvxmYvwVbvNmLn9GbiRXauNmLzV2Zh1Wavw1LcpDc0RHaiojIsJye.jpg)
Volley将HttpClient和HttpURLConnection這兩種方式進行了封裝,避免每次網絡請求進行繁瑣的設定。首先是分别将HttpClient,HttpURLConnection封裝到HttpClientStack和HurlStack兩個類中,兩個類的核心方法是
相比于直接調用HttpClient,HttpURLConnection,已經友善多了,但是HttpClientStack和HttpURLConnection仍是分開的兩種請求方式,而且又有共同的方法,可以進一步的封裝。Goolge提供了BasicNetwork類,把這兩個類再次封裝到一起,對外統一提供public NetworkResponse performRequest(Request<?> request) 方法,并且使用byte[] 的回收池,用于 byte[] 的回收再利用,減少了記憶體的配置設定和回收。至此單純的網絡請求封裝已經差不多了,在對外調用的Volley類中,依據Android API的版本生成****Stack的對象(低版本的Android API HttpURLConnection存在一個bug,詳見官方說明),再利用其構造BasicNetwork的對象,
if (stack == null) {
if (Build.VERSION.SDK_INT >= ) {
stack = new HurlStack();
} else {
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
Network network = new BasicNetwork(stack);
一個處理網絡請求的對象就産生好了。
請求隊列分發、緩存、傳送
一個好的網絡請求架構的功能不隻滿足于封裝基本網絡請求操作,還包括管理N多的網絡請求,請求的緩存,結果的傳送等。
這是一張Volley的流程示意圖:
每産生一個網絡請求,加入到請求集合mCurrentRequests中,首先判斷是否緩存,否則放到網絡隊列mNetworkQueue,是則放入到緩存隊列mCacheQueue。Android的設計中UI主線程不宜進行耗時操作,而讀寫緩存、網絡請求都是典型的耗時操作,如果這時候在主線程執行這些操作,無疑容易産生ANR,影響使用者體驗。Volley預設産生了五個線程供緩存和網絡操作,其中一個用于緩存,四個用于網絡。将mCacheQueue傳給緩存線程,根據請求是否取消、是否讀到緩存及緩存是否過期,決定是否要将目前請求送出到網絡線程從網絡加載資料。如果從緩存中都到有效資料,直接将response傳動到主線程。
網絡請求線程中根據request,調用BasicNetwork進行網絡請求,并将資料傳動到UI線程。
這樣分發,緩存,傳送的流程就差不多了。
細節
除了架構流程,網絡庫要處理的細節也很複雜,例如請求頭的解析,網絡請求Https,Cookie,重試等。需要我們深入到代碼細細體會。我也打算先照着敲一遍代碼,加深印象,不管從整體設計還是細節實作,Volley都值得我學習,哥就是想把代碼寫成這樣子的人,啊哈哈!
很慚愧,做了一點微小的貢獻!