Android 網(wǎng)絡(luò)-Volley的框架結(jié)構(gòu)

經(jīng)典的網(wǎng)絡(luò)請(qǐng)求例子

典型網(wǎng)絡(luò)請(qǐng)求
代碼模型:
- 用URL生成連接 ;
- 得到輸出流(輸出流中寫入數(shù)據(jù)) ;
- 得到輸入流,獲取數(shù)據(jù);

遺留下的問題:

  • Android 系統(tǒng)不允許主線程直接操作網(wǎng)絡(luò)請(qǐng)求,需要在子線程中進(jìn)行;
    子線程的創(chuàng)建銷毀本身就是一種資源消耗,同時(shí)線程生命周期不好控制,會(huì)導(dǎo)致各種使用問題;
  • 網(wǎng)絡(luò)異常的處理。請(qǐng)求重連的時(shí)候怎么處理,怎樣傳遞錯(cuò)誤信息到業(yè)務(wù)層進(jìn)行顯示,緩存怎么弄,容錯(cuò)機(jī)制怎么考慮......需要完善;
  • 每個(gè)地方都寫同樣類似的代碼的時(shí)候,會(huì)出現(xiàn)大量的代碼冗余,需要把相同的東西提出來統(tǒng)一處理,再根據(jù)業(yè)務(wù)情況寫差異性代碼;
  • 代碼應(yīng)該具有向后兼容性,允許不同場(chǎng)景下的定制,或者能夠快速穩(wěn)定的修改/替換內(nèi)部代碼,但是保證業(yè)務(wù)邏輯的穩(wěn)定性;
  • 這個(gè)時(shí)候,我們需要一個(gè)網(wǎng)絡(luò)框架了;

解決問題的思路

  • 頻繁的線程創(chuàng)建銷毀。
    采用線程池的方式,可以讓之前創(chuàng)建的一些線程保存下來,留著之后的請(qǐng)求繼續(xù)使用;因?yàn)榫€程池中保留了一定量的線程,但是網(wǎng)絡(luò)請(qǐng)求數(shù)量是未知的,那么需要一個(gè)隊(duì)列,保存尚未來得及處理的請(qǐng)求,有空閑線程的時(shí)候繼續(xù)處理;
  • 異常的處理
    網(wǎng)絡(luò)請(qǐng)求是異步的,很明顯的是我們需要定義接口,采用回調(diào)的方式,在異常產(chǎn)生的時(shí)候丟到業(yè)務(wù)層;
  • 緩存機(jī)制
    對(duì)于需要緩存的請(qǐng)求,如果之前已經(jīng)拉取過數(shù)據(jù)了,我們就可以直接從本地拿取數(shù)據(jù)加以顯示,不用向服務(wù)器要。一種最簡(jiǎn)單的方式就是將請(qǐng)求數(shù)據(jù)存下來,同時(shí)跟請(qǐng)求數(shù)據(jù)相關(guān)聯(lián),根據(jù)關(guān)聯(lián)規(guī)則存取;
  • 重試機(jī)制
    網(wǎng)絡(luò)請(qǐng)求有時(shí)候會(huì)遇到重定向,會(huì)遇到暫時(shí)性質(zhì)的網(wǎng)絡(luò)問題。那么我們就需要根據(jù)異常原因采取重新連接;
  • 代碼復(fù)用
    好好的分析一下每一個(gè)網(wǎng)絡(luò)請(qǐng)求,發(fā)現(xiàn)它們有太多的相似;比如說都會(huì)openConnection ,都會(huì) 判斷responseCode ,獲取 inputstream 等;不同的點(diǎn)上,似乎只有每次請(qǐng)求的URL ,請(qǐng)求參數(shù),請(qǐng)求方式,以及最后的回調(diào)處理不一樣;我們把相同的代碼封裝起來,不同的代碼,通過參數(shù)的方式傳遞進(jìn)來就好。
  • 向后兼容性/可擴(kuò)展性
    很多時(shí)候我們這個(gè)方面的考慮,都是需要通過接口的方式搞定;一個(gè)接口多個(gè)實(shí)現(xiàn),能夠滿足很多的個(gè)性化需要以及未來的改造;

看看Volley是怎么做的

Volley流程圖.png

** 框架初始化:**

Volley 類提供初始化接口,創(chuàng)建請(qǐng)求管理隊(duì)列RequestQueue;
RequestQueue中持有全局性的操作對(duì)象,跟具體請(qǐng)求無關(guān):
緩存管理接口mCache,負(fù)責(zé)從磁盤上保存讀取之前
網(wǎng)絡(luò)請(qǐng)求控制類mNetwork ,具體實(shí)現(xiàn)單個(gè)網(wǎng)絡(luò)請(qǐng)求的控制類,發(fā)起連接,獲取原始網(wǎng)絡(luò)流數(shù)據(jù);
緩存分發(fā)器mCacheDispatcher ,一個(gè)線程類,負(fù)責(zé)從磁盤讀取數(shù)據(jù)并返回結(jié)果;
網(wǎng)絡(luò)請(qǐng)求分發(fā)起mDispatchers ,線程類數(shù)據(jù),保存著數(shù)個(gè)線程,每個(gè)網(wǎng)絡(luò)請(qǐng)求都是在其中一個(gè)線程中執(zhí)行;
事件傳遞器mDelivery,框架中產(chǎn)生了異常,成功獲取數(shù)據(jù)后都是通過這里回調(diào)出去的;
網(wǎng)絡(luò)請(qǐng)求協(xié)議棧HttpStack,接口類,可以采用不同的實(shí)現(xiàn)方式獲取到http的連接;       

單個(gè)網(wǎng)絡(luò)請(qǐng)求流程:

  以mRequestQueue 的add 方法為入口,傳遞具體的Requst執(zhí)行請(qǐng)求流程;
  Requst中包含有網(wǎng)絡(luò)請(qǐng)求必須的網(wǎng)絡(luò)設(shè)置參數(shù),服務(wù)器請(qǐng)求參數(shù),以及回調(diào)接口;
  mRequestQueue會(huì)根據(jù)緩存情況決定是否從Cache中獲取數(shù)據(jù);               
  不需要緩存數(shù)據(jù)或者緩存數(shù)據(jù)過期,請(qǐng)求會(huì)進(jìn)入網(wǎng)絡(luò)請(qǐng)求隊(duì)列,經(jīng)由mDispachters的分發(fā)后,從網(wǎng)絡(luò)獲取數(shù)據(jù);
  數(shù)據(jù)獲取過程中產(chǎn)生的結(jié)果以及異常信息,經(jīng)由mDelivery回傳到request對(duì)應(yīng)的回調(diào)中;
  于是一個(gè)網(wǎng)絡(luò)請(qǐng)求過程完成。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • AFHTTPRequestOperationManager 網(wǎng)絡(luò)傳輸協(xié)議UDP、TCP、Http、Socket、X...
    Carden閱讀 5,320評(píng)論 0 12
  • 一、簡(jiǎn)歷準(zhǔn)備 1、個(gè)人技能 (1)自定義控件、UI設(shè)計(jì)、常用動(dòng)畫特效 自定義控件 ①為什么要自定義控件? Andr...
    lucas777閱讀 5,388評(píng)論 2 54
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。。。 其實(shí)如果沒有APIManager這一層是沒法使用delegate的,畢竟多個(gè)單...
    yhtang閱讀 5,490評(píng)論 1 23
  • 1、doctype的意義是什么 2、HTML XHTML HTML5的關(guān)系 3、HTML5有什么變化 新的語義...
    9979eb0cd854閱讀 195評(píng)論 0 1
  • 房間還是原來的模樣,一張床,一張桌子,和一個(gè)對(duì)生活無牽無掛的人。犀利的秋風(fēng),吹遍著了這所城市,從南到北。落葉的季節(jié)...
    干掉這一碗閱讀 586評(píng)論 2 9

友情鏈接更多精彩內(nèi)容