教你寫Android網絡框架之Http請求的分發與執行

教你寫Android網絡框架之Http請求的分發與執行

前言

在前兩篇( 教你寫Android網絡框架之基本架構教你寫Android網絡框架之Request、Response類與請求隊列 )博客中,我們已經介紹了SimpleNet框架的基本結構,以及Request、Response、請求隊列的實現,以及爲什麼要這麼設計,這麼設計的考慮是什麼。前兩篇博客中已經介紹了各個角色,今天我們就來剖析另外幾個特別重要的角色,即NetworkExecutor、HttpStack以及ResponseDelivery,它們分別對應的功能是網絡請求線程、Http執行器、Response分發,這三者是執行http請求和處理Response的核心。

我們再來回顧一下,SimpleNet各個角色的分工合作。首先用戶需要創建一個請求隊列,然後將各個請求添加到請求隊列中。多個NetworkExecutor ( 實質上是一個線程 )共享一個消息隊列,在各個NetworkExecutor中循環的取請求隊列中的請求,拿到一個請求,然後通過HttpStack來執行Http請求,請求完成後最終通過ResponseDelivery將Response結果分發到UI線程,保證請求回調執行在UI線程,這樣用戶就可以直接在回調中更新UI。執行流程如圖1.


圖1

還有不太瞭解這幅架構圖的可以參考專欄中的第一篇博客。

NetworkExecutor

作爲SimpleNet中的“心臟”,NetworkExecutor起着非常重要的作用。之所以稱之爲“心臟”,是由於NetworkExecutor的功能是源源不斷地從請求隊列中獲取請求,然後交給HttpStack來執行。它就像汽車中的發動機,人體中的心臟一樣,帶動着整個框架的運行。

NetworkExecutor實質上是一個Thread,在run方法中我們會執行一個循環,不斷地從請求隊列中取得請求,然後交給HttpStack,由於比較簡單我們直接上代碼吧。

在啓動請求隊列時,我們會啓動指定數量的NetworkExecutor ( 參考 教你寫Android網絡框架之Request、Response類與請求隊列)。在構造NetworkExecutor時會將請求隊列以及HttpStack注入進來,這樣NetworkExecutor就具有了兩大元素,即請求隊列和HttpStack。然後在run函數的循環中不斷地取出請求,並且交給HttpStack執行,其間還會判斷該請求是否需要緩存、是否已經有緩存,如果使用緩存、並且已經含有緩存,那麼則使用緩存的結果等。在run函數中執行http請求,這樣就將網絡請求執行在子線程中。執行Http需要HttpStack,但最終我們需要將結果分發到UI線程需要ResponseDelivery,下面我們挨個介紹。

HttpStack

HttpStack只是一個接口,只有一個performRequest函數,也就是執行請求。

HttpStack是網絡請求的真正執行者,有HttpClientStack和HttpUrlConnStack,兩者分別爲Apache的HttpClient和java的HttpURLConnection,關於這兩者的區別請參考:Android訪問網絡,使用HttpURLConnection還是HttpClient? 默認情況下,我們會根據api版本來構建對應的HttpStack,當然用戶也可以自己實現一個HttpStack,然後通過SimpleNet的工廠函數傳遞進來。
例如 :

HttpClientStack和HttpUrlConnStack分別就是封裝了HttpClient和HttpURLConnection的http請求,構建請求、設置header、設置請求參數、解析Response等操作。針對於這一層,我們沒有給出一個抽象類,原因是HttpClient和HttpURLConnection並不屬於同一個類族,他們的行爲雖然都很相似,但是其中涉及到的一些類型卻是不同的。這裏我們給出HttpUrlConnStack的示例,最近比較忙,因此寫的配置比較簡單,有需要的同學自己優化了。

代碼很簡單,就不多說了。

ResponseDelivery

在HttpStack的performRequest函數中,我們會返回一個Response對象,該對象包含了我們請求對應的Response。關於Response類你不太瞭解的可以參考教你寫Android網絡框架之Request、Response類與請求隊列。我們在NetworkExecutor中執行http請求的最後一步會將結果分發給UI線程,主要工作其實就是將請求的回調執行到UI線程,以便用戶可以更新UI等操作。

不管是從緩存中獲取還是從網絡上獲取,我們得到的都是一個Response對象,最後我們通過ResponseDelivery對象將結果分發給UI線程。

ResponseDelivery其實就是封裝了關聯了UI線程消息隊列的Handler,在deliveryResponse函數中將request的deliveryResponse執行在UI線程中。既然我們有了關聯了UI線程的Handler對象,那麼直接構建一個Runnable,在該Runnable中執行request的deliveryResponse函數即可。在Request類的deliveryResponse中,又會調用parseResponse解析Response結果,返回的結果類型就是Request中的T,這個T是在Request子類中指定,例如JsonRequest,那麼返回的Response的結果就是JSONObject。這樣我們就得到了服務器返回的json數據,並且將這個json結果通過回調的形式傳遞給了UI線程。用戶就可以在該回調中更新UI了。
這其中主要就是抽象和泛型,寫框架很多時候泛型是很重要的手段,因此熟悉使用抽象和泛型是面向對象開發的重要一步。
ResponseDelivery代碼如下 :

Request類的deliveryResponse函數。

這樣,整個請求過程就完成了。下面我們總結一下這個過程。

不同用戶的服務器返回的數據格式是不一致的,因此我們定義了Request泛型基類,泛型T就是返回的數據格式類型。比如返回的數據格式爲json,那對應的請求就是JsonRequest,泛型T爲JSONObject,在JsonRequest中覆寫parseResponse函數,將得到的Response中的原始數據轉換成JSONObject。然後將請求放到隊列中,NetworkExecutor將請求分發給HttpStack執行,執行完成之後得到Response對象,最終ResponseDelivery將結果通過請求回調投遞到UI線程。

發佈了24 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章