[轉(zhuǎn)]教你寫Android網(wǎng)絡(luò)框架之基本架構(gòu)

本文轉(zhuǎn)自Mr.Simple的博客,如侵刪

前言

在開發(fā)過程中貌笨,網(wǎng)絡(luò)是我們很重要的一部分耳奕,因此我們就以網(wǎng)絡(luò)框架或者說網(wǎng)絡(luò)模塊開始衅斩。在這個(gè)框架開發(fā)過程中盆顾,我會(huì)整理開發(fā)思路、以及遇到一些設(shè)計(jì)問題時(shí)會(huì)有怎么樣的考慮畏梆、解決方案您宪,當(dāng)然這只是我個(gè)人的觀點(diǎn),大家也可以有自己的實(shí)現(xiàn)奠涌。除了網(wǎng)絡(luò)框架宪巨,后續(xù)的系列還想更新ImageLoader框架、ORM框架溜畅,如果有時(shí)間也會(huì)增加動(dòng)畫框架和微博開發(fā)的系列文章捏卓。當(dāng)然這些框架只是一些簡(jiǎn)單的框架基礎(chǔ),本人水平慈格、時(shí)間有限怠晴,而且已經(jīng)有現(xiàn)成贿肩、成熟的很多框架,我們?cè)谶@里只是以重復(fù)造輪子的態(tài)度去學(xué)習(xí)輪子構(gòu)建過程龄寞,從而達(dá)到能夠造輪子的地步汰规。至于很多細(xì)節(jié)的問題,我們這里就補(bǔ)過多討論了物邑,如果有興趣溜哮,各位可以自行研究。
最后色解,我們暫且把這個(gè)框架命名為Simple_Net_Framework茂嗓,下面我們一起進(jìn)入主題吧。

基本結(jié)構(gòu)

圖1 Simple_Net_Framework的基本結(jié)構(gòu)

SimpleNet框架的基本結(jié)構(gòu)類似于Volley,包括一些命名上也有跟Volley一致科阎。它主要分為四個(gè)部分述吸,最上面的部分為Request,即各種請(qǐng)求類型锣笨。例如返回的數(shù)據(jù)類型為json的對(duì)應(yīng)為JsonRequest蝌矛,返回?cái)?shù)據(jù)字符串的為StringRequest,如果需要上傳文件错英,那么你需要使用MultipartRequest入撒,該請(qǐng)求只支持小文件的上傳,如果上傳的文件過大則會(huì)產(chǎn)生OOM椭岩。
第二部分為消息隊(duì)列茅逮,消息隊(duì)列維護(hù)了提交給網(wǎng)絡(luò)框架的請(qǐng)求列表,并且根據(jù)相應(yīng)的規(guī)則進(jìn)行排序判哥。默認(rèn)情況下更具優(yōu)先級(jí)和進(jìn)入隊(duì)列的順序來執(zhí)行献雅,該隊(duì)列使用的是線程安全的PriorityBlockingQueue<E>,因?yàn)槲覀兊年?duì)列會(huì)被并發(fā)的訪問塌计,因此需要保證訪問的原子性挺身。
第三部分是Executor,也就是網(wǎng)絡(luò)的執(zhí)行者夺荒。該Executor繼承自Thread瞒渠,在run方法中循環(huán)訪問第二部分的請(qǐng)求隊(duì)列,請(qǐng)求完成之后將結(jié)果投遞給UI線程技扼。為了更好的控制請(qǐng)求隊(duì)列伍玖,例如請(qǐng)求排序、取消等操作剿吻,這里我們并沒有使用線程池來操作窍箍,而是自行管理隊(duì)列和Thread的形式,這樣整個(gè)結(jié)構(gòu)也變得更為靈活。
第四部分則是Response投遞類椰棘,在第三部分的Executor中執(zhí)行網(wǎng)絡(luò)請(qǐng)求纺棺,Executor是Thread,但是我們并不能在主線程中更新UI邪狞,因此我們使用ResponseDelivery來封裝Response的投遞祷蝌,保證Response執(zhí)行在UI線程。

每個(gè)部分職責(zé)都相對(duì)單一帆卓,這樣便于日后的升級(jí)和維護(hù)巨朦。

框架分析

圖1中看起來有點(diǎn)像是分層架構(gòu),其實(shí)不是剑令,這個(gè)圖更多的是表達(dá)了它的邏輯順序糊啡,而不是結(jié)構(gòu)。而在我們的應(yīng)用開發(fā)中吁津,分層架構(gòu)是一個(gè)重要的手段棚蓄,如圖2所示。


圖2

但在開發(fā)過程中碍脏,我們往往會(huì)把UI和業(yè)務(wù)層耦合起來梭依,因?yàn)樗鼈兊年P(guān)系太密切了,分解起來并不是那么容易潮酒。高手能夠把復(fù)雜的事情簡(jiǎn)單化睛挚,而分解就是簡(jiǎn)單化的重要手段,分解這個(gè)過程在開發(fā)過程中我們成為重構(gòu)急黎。但是如何分離UI和業(yè)務(wù)層也是本人最近想學(xué)習(xí)的,如果各位有好的解決方案侧到,還希望多多指教勃教。
那么我們就引入了一個(gè)分層概念,為了便于理解你也可以按照如圖1的結(jié)構(gòu)來加深理解匠抗。那么分層有什么優(yōu)缺點(diǎn)呢故源?
優(yōu)點(diǎn):
1.復(fù)雜問題分解簡(jiǎn)單化,每一層負(fù)責(zé)自己的實(shí)現(xiàn)汞贸,并向外提供服務(wù)绳军;
2.職責(zé)分離,復(fù)雜的系統(tǒng)都有很多人員進(jìn)行開發(fā)矢腻,這些功能開發(fā)的管理和集成是個(gè)很嚴(yán)重的問題门驾,分層設(shè)計(jì)實(shí)現(xiàn)之后,每層只需定義好自己的對(duì)外接口多柑,其他依賴層服務(wù)的就可以進(jìn)行開發(fā)奶是;
3.每一層對(duì)其他層都是獨(dú)立的,對(duì)外隱藏實(shí)現(xiàn)細(xì)節(jié),上層無需知道下層的細(xì)節(jié)聂沙,只需調(diào)用接口即可秆麸;
4.有利于標(biāo)準(zhǔn)化。
缺點(diǎn):
1.分層之后對(duì)于領(lǐng)域業(yè)務(wù)的修改有可能需要修改很多層及汉;
2.過多的層次影響性能沮趣。

如上所說,我們的Simple_Net_Framework并不是分層的坷随,而是簡(jiǎn)單的模塊化兔毒,但是理論基礎(chǔ)都是類似的,依賴于抽象而不依賴于實(shí)現(xiàn)甸箱、單一職責(zé)......這里引入分層的概念育叁,這是便于理解,同時(shí)也是希望大家在開發(fā)過程中能夠盡量保證模塊的內(nèi)聚性芍殖、耦合性豪嗽。
再看Simple_Net_Framework,Request是一個(gè)抽象的泛型類豌骏,泛型類型就是返回的Response類型龟梦,例如StringRequest就是繼承自Request<String>。第二部分的RequestQueue依賴于Request窃躲,Request是抽象的计贰,因此任何Request的子類都可以傳遞到請(qǐng)求隊(duì)列中來,它依賴的是抽象Request蒂窒,而不是具體的某個(gè)實(shí)現(xiàn)躁倒,因此保證了可擴(kuò)展性。你可以自己實(shí)現(xiàn)自己所需的Request洒琢,例如大文件的上傳Request秧秉。同理,第三部分的NetworkExecutor也只是依賴于Request抽象衰抑,但這里又引入了一個(gè)類型HttpStack象迎,這個(gè)網(wǎng)絡(luò)請(qǐng)求的真正執(zhí)行者,有HttpClientStack和HttpUrlConnStack呛踊,兩者分別為Apache的HttpClient和java的HttpURLConnection砾淌,關(guān)于這兩者的區(qū)別請(qǐng)參考:Android訪問網(wǎng)絡(luò),使用HttpURLConnection還是HttpClient谭网?汪厨。HttpStack也是一個(gè)抽象,具體使用HttpClient還是HttpURLConnection則由運(yùn)行系統(tǒng)版本來定蜻底,HttpStackFactory會(huì)根據(jù)系統(tǒng)版本給框架返回對(duì)應(yīng)的HttpStack骄崩。最后的ResponseDelivery比較簡(jiǎn)單了聘鳞,只是通過Handler將結(jié)果投遞給UI線程執(zhí)行,也就是執(zhí)行RequestListener的onComplete方法要拂,此時(shí)網(wǎng)絡(luò)執(zhí)行完成抠璃,用戶即可在該方法中更新UI或者相關(guān)的其他的操作。
下面我們?cè)倏纯碨impleNet的工程結(jié)構(gòu)脱惰,如圖3所示搏嗡。

圖3
圖4

這就是Simple_Net_Framework框架的基本結(jié)構(gòu)了
GitHub

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拉一,隨后出現(xiàn)的幾起案子采盒,更是在濱河造成了極大的恐慌,老刑警劉巖蔚润,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件磅氨,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡嫡纠,警方通過查閱死者的電腦和手機(jī)烦租,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來除盏,“玉大人叉橱,你說我怎么就攤上這事≌呷洌” “怎么了窃祝?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)踱侣。 經(jīng)常有香客問我粪小,道長(zhǎng),這世上最難降的妖魔是什么泻仙? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任糕再,我火速辦了婚禮,結(jié)果婚禮上玉转,老公的妹妹穿的比我還像新娘。我一直安慰自己殴蹄,他們只是感情好究抓,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著袭灯,像睡著了一般刺下。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上稽荧,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天橘茉,我揣著相機(jī)與錄音,去河邊找鬼。 笑死畅卓,一個(gè)胖子當(dāng)著我的面吹牛擅腰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播翁潘,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼趁冈,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了拜马?” 一聲冷哼從身側(cè)響起渗勘,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎俩莽,沒想到半個(gè)月后旺坠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扮超,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年取刃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞒津。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝉衣,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出巷蚪,到底是詐尸還是另有隱情病毡,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布屁柏,位于F島的核電站啦膜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏淌喻。R本人自食惡果不足惜僧家,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裸删。 院中可真熱鬧八拱,春花似錦、人聲如沸涯塔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匕荸。三九已至爹谭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間榛搔,已是汗流浹背诺凡。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工东揣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腹泌。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓嘶卧,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親真屯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子脸候,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容