一吃嘿、MVC與MVP
MVC全名是Model View Controller塞关,如圖晕讲,是模型(model)-視圖(view)-控制器(controller)的縮寫贵白,一種軟件設(shè)計(jì)典范抚芦,用一種業(yè)務(wù)邏輯倍谜、數(shù)據(jù)、界面顯示分離的方法組織代碼叉抡,在改進(jìn)和個(gè)性化定制界面及用戶交互的同時(shí)尔崔,不需要重新編寫業(yè)務(wù)邏輯。
其中M層處理數(shù)據(jù)褥民,業(yè)務(wù)邏輯等季春;V層處理界面的顯示結(jié)果;C層起到橋梁的作用消返,來控制V層和M層通信以此來達(dá)到分離視圖顯示和業(yè)務(wù)邏輯層载弄。
android 中的MVC架構(gòu)
Android中界面部分也采用了當(dāng)前比較流行的MVC框架,在Android中:
視圖層(View)
一般采用XML文件進(jìn)行界面的描述撵颊,這些XML可以理解為AndroidApp的View宇攻。使用的時(shí)候可以非常方便的引入。同時(shí)便于后期界面的修改倡勇。邏輯中與界面對(duì)應(yīng)的id不變化則代碼不用修改逞刷,大大增強(qiáng)了代碼的可維護(hù)性。
控制層(Controller)
Android的控制層的重任通常落在了眾多的Activity的肩上妻熊。這句話也就暗含了不要在Activity中寫代碼亲桥,要通過Activity交割Model業(yè)務(wù)邏輯層處理,這樣做的另外一個(gè)原因是Android中的Actiivity的響應(yīng)時(shí)間是5s固耘,如果耗時(shí)的操作放在這里,程序就很容易被回收掉词身。
模型層(Model)
我們針對(duì)業(yè)務(wù)模型厅目,建立的數(shù)據(jù)結(jié)構(gòu)和相關(guān)的類,就可以理解為AndroidApp的Model法严,Model是與View無關(guān)损敷,而與業(yè)務(wù)相關(guān)的(感謝@Xander的講解)。對(duì)數(shù)據(jù)庫(kù)的操作深啤、對(duì)網(wǎng)絡(luò)等的操作都應(yīng)該在Model里面處理拗馒,當(dāng)然對(duì)業(yè)務(wù)計(jì)算等操作也是必須放在的該層的。就是應(yīng)用程序中二進(jìn)制的數(shù)據(jù)溯街。
MVP架構(gòu)
MVP從更早的MVC框架演變過來诱桂,與MVC有一定的相似性:Controller/Presenter負(fù)責(zé)邏輯的處理洋丐,Model提供數(shù)據(jù),View負(fù)責(zé)顯示挥等。
MVP框架由3部分組成:View負(fù)責(zé)顯示友绝,Presenter負(fù)責(zé)邏輯處理,Model提供數(shù)據(jù)肝劲。在MVP模式里通常包含3個(gè)要素(加上View interface是4個(gè)):
View:負(fù)責(zé)繪制UI元素迁客、與用戶進(jìn)行交互(在Android中體現(xiàn)為Activity)
Model:負(fù)責(zé)存儲(chǔ)、檢索辞槐、操縱數(shù)據(jù)(有時(shí)也實(shí)現(xiàn)一個(gè)Model interface用來降低耦合)
Presenter:作為View與Model交互的中間紐帶掷漱,處理與用戶交互的負(fù)責(zé)邏輯。
*View interface:需要View實(shí)現(xiàn)的接口榄檬,View通過View interface與Presenter進(jìn)行交互卜范,降低耦合,方便進(jìn)行單元測(cè)試
兩種模式的主要區(qū)別:
(最主要區(qū)別)View與Model并不直接交互丙号,而是通過與Presenter交互來與Model間接交互先朦。而在MVC中View可以與Model直接交互
通常View與Presenter是一對(duì)一的,但復(fù)雜的View可能綁定多個(gè)Presenter來處理邏輯犬缨。而Controller是基于行為的喳魏,并且可以被多個(gè)View共享,Controller可以負(fù)責(zé)決定顯示哪個(gè)View
Presenter與View的交互是通過接口來進(jìn)行的怀薛,更有利于添加單元測(cè)試刺彩。
UI層一般包括Activity,F(xiàn)ragment枝恋,Adapter等直接和UI相關(guān)的類创倔,UI層的Activity在啟動(dòng)之后實(shí)例化相應(yīng)的Presenter,App的控制權(quán)后移焚碌,由UI轉(zhuǎn)移到Presenter畦攘,兩者之間的通信通過BroadCast、Handler或者接口完成十电,只傳遞事件和結(jié)果知押。
舉個(gè)簡(jiǎn)單的例子,UI層通知邏輯層(Presenter)用戶點(diǎn)擊了一個(gè)Button鹃骂,邏輯層(Presenter)自己決定應(yīng)該用什么行為進(jìn)行響應(yīng)台盯,該找哪個(gè)模型(Model)去做這件事,最后邏輯層(Presenter)將完成的結(jié)果更新到UI層畏线。
MVC静盅、MVP、MVVM區(qū)別
MVVM可以算是MVP的升級(jí)版寝殴,其中的VM是ViewModel的縮寫蒿叠,ViewModel可以理解成是View的數(shù)據(jù)模型和Presenter的合體明垢,ViewModel和View之間的交互通過Data Binding完成,而Data Binding可以實(shí)現(xiàn)雙向的交互栈虚,這就使得視圖和控制層之間的耦合程度進(jìn)一步降低袖外,關(guān)注點(diǎn)分離更為徹底,同時(shí)減輕了Activity的壓力魂务。
三者的差異在于如何粘合View和Model曼验,實(shí)現(xiàn)用戶的交互操作以及變更通知
Controller
Controller接收View的操作事件,根據(jù)事件不同粘姜,或者調(diào)用Model的接口進(jìn)行數(shù)據(jù)操作鬓照,或者進(jìn)行View的跳轉(zhuǎn),從而也意味著一個(gè)Controller可以對(duì)應(yīng)多個(gè)View孤紧。Controller對(duì)View的實(shí)現(xiàn)不太關(guān)心豺裆,只會(huì)被動(dòng)地接收,Model的數(shù)據(jù)變更不通過Controller直接通知View号显,通常View采用觀察者模式監(jiān)聽Model的變化臭猜。
Presenter
Presenter與Controller一樣,接收View的命令押蚤,對(duì)Model進(jìn)行操作蔑歌;與Controller不同的是Presenter會(huì)反作用于View,Model的變更通知首先被Presenter獲得揽碘,然后Presenter再去更新View次屠。一個(gè)Presenter只對(duì)應(yīng)于一個(gè)View。根據(jù)Presenter和View對(duì)邏輯代碼分擔(dān)的程度不同雳刺,這種模式又有兩種情況:Passive View和Supervisor Controller劫灶。
ViewModel
注意這里的“Model”指的是View的Model,跟MVVM中的一個(gè)Model不是一回事掖桦。所謂View的Model就是包含View的一些數(shù)據(jù)屬性和操作的這么一個(gè)東東本昏,這種模式的關(guān)鍵技術(shù)就是數(shù)據(jù)綁定(data binding),View的變化會(huì)直接影響ViewModel枪汪,ViewModel的變化或者內(nèi)容也會(huì)直接體現(xiàn)在View上涌穆。這種模式實(shí)際上是框架替應(yīng)用開發(fā)者做了一些工作,開發(fā)者只需要較少的代碼就能實(shí)現(xiàn)比較復(fù)雜的交互料饥。
參考鏈接:Android App的設(shè)計(jì)架構(gòu)
二、LookLook案例
可以閱讀知乎日?qǐng)?bào)朱监,網(wǎng)易頭條岸啡,每日推送一張妹子圖片和視頻,是一個(gè)精美的閱讀軟件赫编。遵循Google Meterial 設(shè)計(jì)風(fēng)格巡蘸,加入了一些5.0以上的新特性奋隶,閱讀體驗(yàn)絕不遜色于官方的app。
架構(gòu):MVP
圖片加載:Glide
網(wǎng)絡(luò)請(qǐng)求:RxJava & Retrofit+okhttp
界面:遵循Google Meterial 設(shè)計(jì)風(fēng)格
其他:Cardview悦荒,RecycleView唯欣,Butterknife,PhotoView
項(xiàng)目地址github:https://github.com/xinghongfei/LookLook
參考鏈接:2016年最值得學(xué)習(xí)的五大開源項(xiàng)目 - 簡(jiǎn)書
三搬味、學(xué)習(xí)案例前的基礎(chǔ)學(xué)習(xí)
先貼兩個(gè)參考鏈接:
Android網(wǎng)絡(luò)請(qǐng)求心路歷程 - 簡(jiǎn)書
Android 各大網(wǎng)絡(luò)請(qǐng)求庫(kù)的比較及實(shí)戰(zhàn) - 區(qū)長(zhǎng)的專欄
- 博客頻道 - CSDN.NET
因?yàn)閡rl是存在于請(qǐng)求行中的境氢。
所以Get與Post區(qū)別本質(zhì)就是參數(shù)是放在請(qǐng)求行中還是放在請(qǐng)求體中
當(dāng)然無論用哪種都能放在請(qǐng)求頭中。一般在請(qǐng)求頭中放一些發(fā)送端的常量碰纬。
請(qǐng)求是鍵值對(duì)萍聊,但返回?cái)?shù)據(jù)我們常用Json。
對(duì)于內(nèi)存中的結(jié)構(gòu)數(shù)據(jù)悦析,肯定要用數(shù)據(jù)描述語(yǔ)言將對(duì)象序列化成文本寿桨,再用Http傳遞,接收端并從文本還原成結(jié)構(gòu)數(shù)據(jù)。
對(duì)象(服務(wù)器)<-->文本(Http傳輸)<-->對(duì)象(移動(dòng)端) 强戴。
HttpClient & HttpURLConnection
這兩種方式都支持HTTPS協(xié)議亭螟、以流的形式進(jìn)行上傳和下載、配置超時(shí)時(shí)間骑歹、IPv6预烙、以及連接池等功能。在Android 2.2版本之前陵刹,HttpClient擁有較少的bug默伍,因此使用它是最好的選擇。
而在Android 2.3版本及以后衰琐,HttpURLConnection則是最佳的選擇也糊。它的API簡(jiǎn)單,體積較小羡宙,因而非常適用于Android項(xiàng)目狸剃。壓縮和緩存機(jī)制可以有效地減少網(wǎng)絡(luò)訪問的流量,在提升速度和省電方面也起到了較大的作用狗热。對(duì)于新的應(yīng)用程序應(yīng)該更加偏向于使用HttpURLConnection钞馁,因?yàn)樵谝院蟮墓ぷ鳟?dāng)中我們也會(huì)將更多的時(shí)間放在優(yōu)化HttpURLConnection上面。
在子線程進(jìn)行耗時(shí)操作匿刮,完成后通過Handler將更新UI的操作發(fā)送到主線程執(zhí)行僧凰。這就叫異步。Handler是一個(gè)Android線程模型中重要的東西熟丸,與網(wǎng)絡(luò)無關(guān)便不說了训措。關(guān)于Handler不了解就先去Google一下。
但這樣寫好難看绩鸣。異步通常伴隨者他的好基友回調(diào)化借。
這是通過回調(diào)封裝的Utils類。
每次都new Thread,new Handler消耗過大
沒有異常處理機(jī)制
沒有緩存機(jī)制
沒有完善的API(請(qǐng)求頭,參數(shù),編碼,攔截器等)與調(diào)試模式
沒有Https
Volley&OkHttp應(yīng)該是現(xiàn)在最常用的網(wǎng)絡(luò)請(qǐng)求庫(kù)。用法也非常相似。都是用構(gòu)造請(qǐng)求加入請(qǐng)求隊(duì)列的方式管理網(wǎng)絡(luò)請(qǐng)求鸭丛。
Retrofit是一個(gè)Square開發(fā)的類型安全的REST安卓客戶端請(qǐng)求庫(kù)鼠哥。這個(gè)庫(kù)為網(wǎng)絡(luò)認(rèn)證、API請(qǐng)求以及用OkHttp發(fā)送網(wǎng)絡(luò)請(qǐng)求提供了強(qiáng)大的框架 呆贿。
對(duì)于圖片的傳輸同衣,就像上面的登錄接口的avatar字段前弯,并不會(huì)直接把圖片寫在返回內(nèi)容里询枚,而是給一個(gè)圖片的地址。需要時(shí)再去加載尝胆。
Fresco是Facebook公司的黑科技贪染。光看功能介紹就看出非常強(qiáng)大。使用方法官方博客說的夠詳細(xì)了。
真三級(jí)緩存,變換后的BItmap(內(nèi)存),變換前的原始圖片(內(nèi)存)鳄乏,硬盤緩存水援。
在內(nèi)存管理上做到了極致。對(duì)于重度圖片使用的APP應(yīng)該是非常好的。
所以我更喜歡Glide,作者是bumptech。這個(gè)庫(kù)被廣泛的運(yùn)用在google的開源項(xiàng)目中芯杀,包括2014年google I/O大會(huì)上發(fā)布的官方app端考。
這里有詳細(xì)介紹跛梗。直接使用ImageView即可,無需初始化,極簡(jiǎn)的API粉寞,豐富的拓展巧还,鏈?zhǔn)秸{(diào)用都是我喜歡的。
ButterKnife使用
它的具體優(yōu)勢(shì):
1.強(qiáng)大的View綁定和Click事件處理功能褒搔,簡(jiǎn)化代碼阶牍,提升開發(fā)效率
2.方便的處理Adapter里的ViewHolder綁定問題
3.運(yùn)行時(shí)不會(huì)影響APP效率惧辈,使用配置方便
4.代碼清晰,可讀性強(qiáng)