Android Volley 非同步網路請求分析

codeceo發表於2015-07-23

Volley下載

Google I/O 2013 大會上釋出的 Android 非同步網路請求框架和圖片載入框架。
試用場景:適合資料量小,通訊頻繁的網路操作。

git clone https://android.googlesource.com/platform/frameworks/volley

Volley架構

Volley 非同步網路請求分析

Volley Architect

如上官方給出的Volley架構圖,藍色為主執行緒,綠色為快取執行緒,橙色是網路執行緒。

總的來說,就是一個請求佇列和三種執行緒,UI執行緒(1個),Cache執行緒(1個)和Network執行緒(預設是4個)。

  • UI執行緒負責新增請求任務,執行任務結果;
  • Cache執行緒負責檢查快取,命中後直接將任務結果分發到主執行緒;
  • Network執行緒由多個任務執行緒(NetworkDispatcher)組成的,相當於一個大小為size的執行緒池,這些執行緒會同時啟動,並持續的從任務佇列中獲取待執行的任務,任務執行完後會將結果分發到UI執行緒。

先簡介一下三個類的作用:

  • Volley.java:Volley對外暴露的主類,通過 newRequestQueue(…) 函式新建並啟動一個請求佇列RequestQueue。
  • Request:請求的抽象類。StringRequest、JsonRequest、ImageRequest 都是它的子類,表示某種型別的請求。可擴充套件性強。
  • RequestQueue.java:請求佇列,裡面包含一個CacheDispatcher(用於處理走快取請求的排程執行緒)、NetworkDispatcher陣列(用於處理走網路請求的排程執行緒),一個ResponseDelivery(返回結果分發介面),通過 start() 函式啟動時會啟動CacheDispatcher和NetworkDispatchers。

然後看建立請求佇列方法內的程式碼:

public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
    ...

    Network network = new BasicNetwork(stack);

    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
    queue.start();

    return queue;
}

看到這裡,需要了解三個類的作用:

  • HttpStack.java:處理HTTP請求,返回請求結果。目前Volley中有基於 HttpURLConnection 的 HurlStack 和 基於 Apache HttpClient 的HttpClientStack。
  • Network.java:呼叫HttpStack處理請求,並將結果轉換為可被ResponseDelivery處理的NetworkResponse。
  • Cache.java:快取請求結果,Volley預設使用的是基於sdcard快取的DiskBasedCache。NetworkDispatcher得到請求結果後判斷是否需要儲存在 Cache,CacheDispatcher會從 Cache 中取快取結果。

建立Network需要HttpStatck,如果newRequestQueue傳入的stack為null,API Level >= 9,採用基於 HttpURLConnection 的 HurlStack;小於 9,採用基於 HttpClient 的 HttpClientStack。

if (stack == null) {
    if (Build.VERSION.SDK_INT >= 9) {
        stack = new HurlStack();
    } else {
        // Prior to Gingerbread, HttpUrlConnection was unreliable.
        // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
        stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
    }
}

處理HTTP請求的HttpStatck也可以自定義,比如使用OKHttp,具體可以參見我的另一篇文章使用OKHttp處理Volley的底層HTTP請求

接下來啟動所需的所有執行緒:

public void start() {
    stop();  // Make sure any currently running dispatchers are stopped.
    // Create the cache dispatcher and start it.
    mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
    mCacheDispatcher.start();

    // Create network dispatchers (and corresponding threads) up to the pool size.
    for (int i = 0; i < mDispatchers.length; i++) {
        NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
                mCache, mDelivery);
        mDispatchers[i] = networkDispatcher;
        networkDispatcher.start();
    }
}
  • CacheDispatcher.java:繼承自Thread,用於排程處理「快取請求」。啟動後會不斷從快取請求佇列中取請求處理,佇列為空則等待,請求處理結束則將結果傳遞給ResponseDelivery去執行後續處理。當結果未快取過、快取失效或快取需要重新整理的情況下,該請求都需要重新進入NetworkDispatcher去排程處理。
  • NetworkDispatcher.java:繼承自Thread,用於排程處理「網路請求」。啟動後會不斷從網路請求佇列中取請求處理,佇列為空則等待,請求處理結束則將結果傳遞給ResponseDelivery去執行後續處理,並判斷結果是否要進行快取。
  • ResponseDelivery.java:分發結果的interface,postResponse以及postError。

接下來再回頭看一下Volley的架構圖。

  • 第一步:把請求加入快取佇列
  • 第二步:「快取排程執行緒」CacheDispatcher從快取佇列中取出一個請求,如果快取命中,就讀取快取響應並解析,然後將結果返回到主執行緒
  • 第三步:快取未命中,請求被加入網路請求佇列,「網路排程執行緒」NetworkDispatcher輪詢取出請求,HTTP請求傳輸,解析響應,寫入快取,然後將結果返回到主執行緒

相關文章