新聞中心
1、概述

成都創(chuàng)新互聯(lián)是專(zhuān)業(yè)的資溪網(wǎng)站建設(shè)公司,資溪接單;提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專(zhuān)業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行資溪網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專(zhuān)業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專(zhuān)業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
Databinding 是一種框架,MVVM是一種模式,兩者的概念是不一樣的。我的理解DataBinding是一個(gè)實(shí)現(xiàn)數(shù)據(jù)和UI綁定的框架,只是一個(gè)實(shí)現(xiàn)MVVM模式的工具。ViewModel和View可以通過(guò)DataBinding來(lái)實(shí)現(xiàn)單向綁定和雙向綁定,這套UI和數(shù)據(jù)之間的動(dòng)態(tài)監(jiān)聽(tīng)和動(dòng)態(tài)更新的框架Google已經(jīng)幫我們做好了。在MVVM模式中ViewModel和View是用綁定關(guān)系來(lái)實(shí)現(xiàn)的,所以有了DataBinding 使我們構(gòu)建Android MVVM 應(yīng)用程序成為可能。
之前看了很多關(guān)于DataBinding的博客和相關(guān)的一些Demo,大多數(shù)就是往xml布局文件傳入一些數(shù)據(jù),然后把這些數(shù)據(jù)綁定到控件上( 如TextView binding:text=“@{user.name} ),接著在這些控件上(如Button binding:setOnClickListener=”@{user.listener}”) 設(shè)置一些事件到控件上,基本講述都是DataBinding的基本用法。但是并沒(méi)有人告訴你把一個(gè)onClickListener 寫(xiě)到一個(gè)類(lèi)并把這個(gè)listener綁定到xml里面上是不是不太好,也沒(méi)有人告訴你這個(gè)和xml布局綁定的ViewModel類(lèi)應(yīng)該放哪些數(shù)據(jù),應(yīng)該做什么事?應(yīng)該如何設(shè)計(jì)?更是很少有博文來(lái)告訴你在Android 中如何通過(guò)Data Binding 去構(gòu)建MVVM 的應(yīng)用框架。這也就是是本篇文章的重點(diǎn)。接下來(lái),我們先來(lái)看看什么是MVVM,然后在一步一步來(lái)設(shè)計(jì)整個(gè)應(yīng)用程序框架。
源碼地址 https://github.com/Kelin-Hong/MVVMLight
2、MVC、MVP、MVVM
首先,我們先大致了解Android開(kāi)發(fā)中常見(jiàn)的模式,以便我們更深入了解MVVM 模式。
- MVC
View:對(duì)應(yīng)于xml布局文件
Model:實(shí)體模型
Controllor:對(duì)應(yīng)于Activity業(yè)務(wù)邏輯,數(shù)據(jù)處理和UI處理
從上面看起來(lái)各個(gè)組件的職責(zé)視乎還挺耦合MVC的,但是打開(kāi)Android的一個(gè)Activity文件,一看一言難盡, Android中經(jīng)常會(huì)出現(xiàn)數(shù)千行的Activity代碼,究其原因,Android中純粹作為View的各個(gè)XML視圖功能太弱,Activity基本上都是View和Controller的合體,既要負(fù)責(zé)視圖的顯示又要加入控制邏輯,承擔(dān)的功能過(guò)多,代碼量大也就不足為奇。所有更貼切的目前常規(guī)的開(kāi)發(fā)說(shuō)應(yīng)該是View-Model 模式,大部分都是通過(guò)Activity的協(xié)調(diào),連接,和處理邏輯的。
- MVP
View: 對(duì)應(yīng)于Activity和xml,負(fù)責(zé)View的繪制以及與用戶(hù)交互
Model: 依然是實(shí)體模型
Presenter: 負(fù)責(zé)完成View于Model間的交互和業(yè)務(wù)邏輯
在Android開(kāi)發(fā)中MVP的設(shè)計(jì)思想用得比較多,利用MVP的設(shè)計(jì)模型可以把部分的邏輯的代碼從Fragment和Activity業(yè)務(wù)的邏輯移出來(lái),在Presenter中持有View(Activity或者Fragment)的引用,然后在Presenter調(diào)用View暴露的接口對(duì)視圖進(jìn)行操作,這樣有利于把視圖操作和業(yè)務(wù)邏輯分開(kāi)來(lái)。MVP能夠讓Activity成為真正的View而不是View和Control的合體,Activity只做UI相關(guān)的事。但是這個(gè)模式還是存在一些不好的地方,比較如說(shuō):
- Activity需要實(shí)現(xiàn)各種跟UI相關(guān)的接口,同時(shí)要在Activity中編寫(xiě)大量的事件,然后在事件處理中調(diào)用presenter的業(yè)務(wù)處理方法,View和Presenter只是互相持有引用并互相做回調(diào),代碼不美觀。
- 這種模式中,程序的主角是UI,通過(guò)UI事件的觸發(fā)對(duì)數(shù)據(jù)進(jìn)行處理,更新UI就有考慮線(xiàn)程的問(wèn)題。而且UI改變后牽扯的邏輯耦合度太高,一旦控件更改(比較TextView 替換 EditText等)牽扯的更新UI的接口就必須得換。
復(fù)雜的業(yè)務(wù)同時(shí)會(huì)導(dǎo)致presenter層太大,代碼臃腫的問(wèn)題。
- MVVM
View: 對(duì)應(yīng)于Activity和xml,負(fù)責(zé)View的繪制以及與用戶(hù)交互
Model: 實(shí)體模型
ViewModel: 負(fù)責(zé)完成View于Model間的交互,負(fù)責(zé)業(yè)務(wù)邏輯
MVVM的目標(biāo)和思想MVP類(lèi)似,利用數(shù)據(jù)綁定(Data Binding)、依賴(lài)屬性(Dependency Property)、命令(Command)、路由事件(Routed Event)等新特性,打造了一個(gè)更加靈活高效的架構(gòu)。
- 數(shù)據(jù)驅(qū)動(dòng)
在MVVM中,以前開(kāi)發(fā)模式中必須先處理業(yè)務(wù)數(shù)據(jù),然后根據(jù)的數(shù)據(jù)變化,去獲取UI的引用然后更新UI,通過(guò)也是通過(guò)UI來(lái)獲取用戶(hù)輸入,而在MVVM中,數(shù)據(jù)和業(yè)務(wù)邏輯處于一個(gè)獨(dú)立的View Model中,ViewModel只要關(guān)注數(shù)據(jù)和業(yè)務(wù)邏輯,不需要和UI或者控件打交道。由數(shù)據(jù)自動(dòng)去驅(qū)動(dòng)UI去自動(dòng)更新UI,UI的改變又同時(shí)自動(dòng)反饋到數(shù)據(jù),數(shù)據(jù)成為主導(dǎo)因素,這樣使得在業(yè)務(wù)邏輯處理只要關(guān)心數(shù)據(jù),方便而且簡(jiǎn)單很多。
- 低耦合度
MVVM模式中,數(shù)據(jù)是獨(dú)立于UI的,ViewModel只負(fù)責(zé)處理和提供數(shù)據(jù),UI想怎么處理數(shù)據(jù)都由UI自己決定,ViewModel 不涉及任何和UI相關(guān)的事也不持有UI控件的引用,即使控件改變(TextView 換成 EditText)ViewModel 幾乎不需要更改任何代碼,專(zhuān)注自己的數(shù)據(jù)處理就可以了,如果是MVP遇到UI更改,就可能需要改變獲取UI的方式,改變更新UI的接口,改變從UI上獲取輸入的代碼,可能還需要更改訪(fǎng)問(wèn)UI對(duì)象的屬性代碼等等。
- 更新 UI
在MVVM中,我們可以在工作線(xiàn)程中直接修改View Model的數(shù)據(jù)(只要數(shù)據(jù)是線(xiàn)程安全的),剩下的數(shù)據(jù)綁定框架幫你搞定,很多事情都不需要你去關(guān)心。
- 團(tuán)隊(duì)協(xié)作
MVVM的分工是非常明顯的,由于View和View Model之間是松散耦合的。一個(gè)是處理業(yè)務(wù)和數(shù)據(jù),一個(gè)是專(zhuān)門(mén)的UI處理。完全有兩個(gè)人分工來(lái)做,一個(gè)做UI(xml 和 Activity)一個(gè)寫(xiě)ViewModel,效率更高。
- 可復(fù)用性
一個(gè)View Model復(fù)用到多個(gè)View中,同樣的一份數(shù)據(jù),用不同的UI去做展示,對(duì)于版本迭代頻繁的UI改動(dòng),只要更換View層就行,對(duì)于如果想在UI上的做AbTest 更是方便的多。
- 單元測(cè)試
View Model里面是數(shù)據(jù)和業(yè)務(wù)邏輯,View中關(guān)注的是UI,這樣的做測(cè)試是很方便的,完全沒(méi)有彼此的依賴(lài),不管是UI的單元測(cè)試還是業(yè)務(wù)邏輯的單元測(cè)試,都是低耦合的。
通過(guò)上面對(duì)MVVM的簡(jiǎn)述和其他兩種模式的對(duì)比,我們發(fā)現(xiàn)MVVM對(duì)比MVC和MVP來(lái)說(shuō)還是存在比較大的優(yōu)勢(shì),雖然目前Android開(kāi)發(fā)中可能真正在使用MVVM的很少,但是是值得我們?nèi)プ鲆恍┨接懞驼{(diào)研。
3、如何構(gòu)建MVVM應(yīng)用程序
1). 如何分工
構(gòu)建MVVM框架首先要具體了解各個(gè)模塊的分工,接下來(lái)我們來(lái)講解View,ViewModel,Model 的它們各自的職責(zé)所在。
- View
View層做的就是和UI相關(guān)的工作,我們只在XML和Activity或Fragment寫(xiě)View層的代碼,View層不做和業(yè)務(wù)相關(guān)的事,也就是我們的Activity 不寫(xiě)和業(yè)務(wù)邏輯相關(guān)代碼,也不寫(xiě)需要根據(jù)業(yè)務(wù)邏輯來(lái)更新UI的代碼,因?yàn)楦耈I通過(guò)Binding實(shí)現(xiàn),更新UI在ViewModel里面做(更新綁定的數(shù)據(jù)源即可),Activity 要做的事就是初始化一些控件(如控件的顏色,添加 RecyclerView 的分割線(xiàn)),Activity可以更新UI,但是更新的UI必須和業(yè)務(wù)邏輯和數(shù)據(jù)是沒(méi)有關(guān)系的,只是單純的根據(jù)點(diǎn)擊或者滑動(dòng)等事件更新UI(如 根據(jù)滑動(dòng)顏色漸變、根據(jù)點(diǎn)擊隱藏等單純UI邏輯),Activity(View層)是可以處理UI事件,但是處理的只是處理UI自己的事情,View層只處理View層的事。簡(jiǎn)單的說(shuō):View層不做任何業(yè)務(wù)邏輯、不涉及操作數(shù)據(jù)、不處理數(shù)據(jù)、UI和數(shù)據(jù)嚴(yán)格的分開(kāi)。
- ViewModel
ViewModel層做的事情剛好和View層相反,ViewModel 只做和業(yè)務(wù)邏輯和業(yè)務(wù)數(shù)據(jù)相關(guān)的事,不做任何和UI、控件相關(guān)的事,ViewModel 層不會(huì)持有任何控件的引用,更不會(huì)在ViewModel中通過(guò)UI控件的引用去做更新UI的事情。ViewModel就是專(zhuān)注于業(yè)務(wù)的邏輯處理,操作的也都是對(duì)數(shù)據(jù)進(jìn)行操作,這些個(gè)數(shù)據(jù)源綁定在相應(yīng)的控件上會(huì)自動(dòng)去更改UI,開(kāi)發(fā)者不需要關(guān)心更新UI的事情。DataBinding 框架已經(jīng)支持雙向綁定,這使得我們?cè)诳梢酝ㄟ^(guò)雙向綁定獲取View層反饋給ViewModel層的數(shù)據(jù),并進(jìn)行操作。關(guān)于對(duì)UI控件事件的處理,我們也希望能把這些事件處理綁定到控件上,并把這些事件統(tǒng)一化,方便ViewModel對(duì)事件的處理和代碼的美觀。為此我們通過(guò)BindingAdapter 對(duì)一些常用的事件做了封裝,把一個(gè)個(gè)事件封裝成一個(gè)個(gè)Command,對(duì)于每個(gè)事件我們用一個(gè)ReplyCommand
- Model
Model 的職責(zé)很簡(jiǎn)單,基本就是實(shí)體模型(Bean)同時(shí)包括Retrofit 的Service ,ViewModel 可以根據(jù)Model 獲取一個(gè)Bean的Observable
2). 如何協(xié)作
關(guān)于協(xié)作,我們先來(lái)看下面的一張圖:
圖 1
上圖反應(yīng)了MVVM框架中各個(gè)模塊的聯(lián)系和數(shù)據(jù)流的走向,由上圖可知View和Model 直接是解耦的,是沒(méi)有直接聯(lián)系的,也就是我之前說(shuō)到的View 不做任何和業(yè)務(wù)邏輯和數(shù)據(jù)處理相關(guān)的事。我們從每個(gè)模塊一一拆分來(lái)看。那么我們重點(diǎn)就是下面的三個(gè)協(xié)作。
- ViewModel與View的協(xié)作
- ViewModel與Model的協(xié)作
- ViewModel與ViewModel的協(xié)作
ViewModel與View的協(xié)作
圖 2
圖 2 中ViewModel 和View 是通過(guò)綁定的方式連接在一起的,綁定的一種是數(shù)據(jù)綁定,一種是命令綁定。數(shù)據(jù)的綁定 DataBinding 已經(jīng)提供好了,簡(jiǎn)單的定義一些ObservableField就能把數(shù)據(jù)和控件綁定在一起了(如TextView的text屬性),但是DataBinding框架提供的不夠全面,比如說(shuō)如何讓一個(gè)URL綁定到一個(gè)ImageView讓這個(gè)ImageView能自動(dòng)去加載url指定的圖片,如何把數(shù)據(jù)源和布局模板綁定到一個(gè)ListView,讓ListView可以不需要去寫(xiě)Adapter和ViewHolder 相關(guān)的東西,而只是通過(guò)簡(jiǎn)單的綁定的方式把ViewModel的數(shù)據(jù)源綁定到Xml的控件里面就能快速的展示列表呢?這些就需要我們做一些工作和簡(jiǎn)單的封裝。MVVM Light Toolkit 已經(jīng)幫我們做了一部分的工作,詳情可以查看MVVM Light Toolkit 使用指南。關(guān)于事件綁定也是一樣,MVVM Light Toolkit 做了簡(jiǎn)單的封裝,對(duì)于每個(gè)事件我們用一個(gè)ReplyCommand
由 圖 1 中ViewModel的模塊中我們可以看出ViewModel類(lèi)下面一般包含下面5個(gè)部分:
- Context (上下文)
- Model (數(shù)據(jù)模型Bean)
- Data Field (數(shù)據(jù)綁定)
- Command (命令綁定)
- Child ViewModel (子ViewModel)
我們先來(lái)看下示例代碼,然后在一一講解5個(gè)部分是干嘛用的:
- //context
- private Activity context;
- //model(數(shù)據(jù)模型Bean)
- private NewsService.News news;
- private TopNewsService.News topNews;
- //數(shù)據(jù)綁定(data field)
- public final ObservableField
imageUrl = new ObservableField<>();
分享標(biāo)題:如何構(gòu)建AndroidMVVM應(yīng)用程序
標(biāo)題URL:http://www.dlmjj.cn/article/cddcgdc.html


咨詢(xún)
建站咨詢(xún)
