Android-Mvvm模式和LiveData的使用以及DataBinding的關(guān)系

轉(zhuǎn)載請(qǐng)標(biāo)明出處http://www.reibang.com/p/7fe5c2f9459a

前言:在上一篇http://www.reibang.com/p/fb8d33168f57中說(shuō)到要把MVVM的坑補(bǔ)上挫以。哪有跳過(guò)MVVM學(xué)DataBinding就算的道理顾瞪。
但是由于日常工作任務(wù)以及個(gè)人的緣故膏执,拖了半個(gè)月。經(jīng)過(guò)一段時(shí)間的學(xué)習(xí)枕稀,才發(fā)現(xiàn)DataBinding是構(gòu)建MVVM的工具。
很早以前就使用的MVC過(guò)于耦合,Activity十分臃腫近忙。MVP模式雖然解決了MVC耦合的問(wèn)題,但是對(duì)象持有的內(nèi)存泄露智润,和V層一定程度耦合及舍,以及P層接口過(guò)多代碼臃腫。都是潛在的問(wèn)題窟绷,日常開(kāi)發(fā)中經(jīng)尘饴辏可見(jiàn)。相較之下兼蜈,學(xué)習(xí)了MVVM就一個(gè)感覺(jué)攘残,真香。

1.MVVM是什么

MVVM是Model-View-ViewModel的簡(jiǎn)寫(xiě)为狸。最早是Web開(kāi)發(fā)的概念歼郭,它本質(zhì)上就是MVC 的改進(jìn)版。MVVM 就是將其中的View 的狀態(tài)和行為抽象化钥平,讓我們將視圖 UI 和業(yè)務(wù)邏輯分開(kāi)实撒。由ViewModel進(jìn)行數(shù)據(jù)邏輯的處理,View專注視圖UI。Model和傳統(tǒng)意義的model有些許不同,這里不止是指實(shí)體對(duì)象倒得,還包括了數(shù)據(jù)的獲取,存儲(chǔ)负敏。MVVM是由數(shù)據(jù)驅(qū)動(dòng)UI的,且ViewModel可復(fù)用秘蛇,View和ViewModel之間十分解耦其做,可以在日常工作中分開(kāi)編寫(xiě)。

2.MVVM的使用

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:24.2.0'
    implementation "android.arch.lifecycle:extensions:1.1.0"
}

這里會(huì)用到lifecycle組件赁还,lifecycle是Google提供的應(yīng)用組件生命周期管理組件妖泄。簡(jiǎn)單來(lái)說(shuō),它可以很好的對(duì)activity艘策,F(xiàn)ragment等的生命周期進(jìn)行監(jiān)控管理蹈胡,從而很好的避免內(nèi)存泄漏甚至崩潰。官方文檔中也有描述。

image

3.MVVM中的框架搭建

3.1ViewModel

官方提供了ViewModel類(lèi)供我們繼承罚渐。viewmodel是貫穿于整個(gè)activity生命周期的却汉,只有activity銷(xiāo)毀之后,viewmodel生命周期才結(jié)束荷并。ViewModel只關(guān)注數(shù)據(jù)業(yè)務(wù)邏輯合砂,ViewModel中不做視圖相關(guān)的操作,更不持有控件引用源织。通常會(huì)搭配LiveData來(lái)使用翩伪,下面會(huì)提及。

public class UserViewModel extends ViewModel {
 }

如果你在viewmodel中需要用到上下文雀鹃,可以繼承AndroidViewModel幻工。

public class UserViewModel extends AndroidViewModel {
    public UserViewModel(@NonNull Application application) {
        super(application);
    }
}

通常,是使用DataBinding的ObservableFields(實(shí)現(xiàn)了BaseObservable)實(shí)現(xiàn)對(duì)象可觀察的黎茎。

public class UserViewModel extends AndroidViewModel {
    ObservableField<User> liveDataUser = new ObservableField<>();
}

但是更多的我們會(huì)使用LiveData,LiveData能實(shí)現(xiàn)對(duì)象觀察当悔,還可以感知組件生命周期傅瞻,ObservableFields則需要自己根據(jù)DataBinding手動(dòng)處理生命周期問(wèn)題。且LiveData可以主動(dòng)調(diào)用postValue盲憎,setValue通知UI嗅骄,且LiveData可以更好的許多架構(gòu)組件 (如Room、WorkManager) 相互配合使用饼疙。這個(gè)在Google Android開(kāi)發(fā)者官方賬號(hào)也有提到溺森。我們?cè)趘iewmodel中使用LiveData,然后在view中配合LiveData的observe方法窑眯,即可觀察數(shù)據(jù)變化屏积。

public class UserViewModel extends AndroidViewModel {
    MutableLiveData<User> liveDataUser = new MutableLiveData<>();
    public UserViewModel(@NonNull Application application) {
        super(application);
    }
    public LiveData<User> Login() {
        //vm傾向于對(duì)數(shù)據(jù)的處理,而不是對(duì)于view的處理
        UserBiz userBiz = new UserBiz();
        //例如數(shù)據(jù)層網(wǎng)絡(luò)請(qǐng)求操作
        userBiz.Login("基佬2", new ILoginListener() {
            @Override
            public void onSuccess(User user) {
                liveDataUser.postValue(user);
            }
            @Override
            public void onFail() {
            }
        });
        return liveDataUser;
    }
}

3.2View

這里activity就是我們真正意義上的View,并且View并不在意數(shù)據(jù)業(yè)務(wù)邏輯磅甩,不操作不處理數(shù)據(jù)炊林,他只在乎UI該做的事情。

public class MainActivity extends AppCompatActivity {
    private UserViewModel mNameViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        mNameViewModel.getUsers().observe(this, new Observer<List<User>>() {
//            @Override
//            public void onChanged(List<User> users) {
//            }
//        });
        mNameViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
        mNameViewModel.Login().observe(this, (User users) -> {
            //我們更傾向于讓activity專注于視圖的處理卷要,而不是對(duì)于數(shù)據(jù)的處理渣聚。
            //訂閱LiveData中User列表數(shù)據(jù)變化,以lambda形式定義Observer,進(jìn)行監(jiān)聽(tīng)
            Toast.makeText(this, "加載成功:"+users.toString(), Toast.LENGTH_SHORT).show();
        });
    }
}

像這樣僧叉,View就可以通過(guò)ViewModelProviders找到你的ViewModel奕枝,調(diào)用方法且通過(guò)上文提到的LiveData監(jiān)聽(tīng)訂閱。在View里只做View的事情瓶堕,不涉及數(shù)據(jù)隘道。

3.3Model

這里Model不單是實(shí)體模型,還包括了網(wǎng)絡(luò)請(qǐng)求,服務(wù)等薄声。是對(duì)數(shù)據(jù)的獲取当船,存儲(chǔ)的操作的。

public class UserBiz implements IUserBiz {
    @Override
    public void Login(String name, ILoginListener loginListener) {
        User user = new User();
        //模擬網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù)
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                user.setName(name);
                user.setAge("18歲2");
                user.setGender("男2");
                loginListener.onSuccess(user);
            }
        }).start();
    }
}

最終就可以實(shí)現(xiàn)5S后彈出toast的效果默辨。甚至德频,如果你想達(dá)到databinding的單向綁定,只需要findViewById配合控件set即可缩幸。很簡(jiǎn)單的一個(gè)數(shù)據(jù)變化壹置,UI變化的過(guò)程。

image

而且就算是想到達(dá)到雙向綁定的效果表谊,通過(guò)findViewById找到控件對(duì)控件進(jìn)行監(jiān)聽(tīng)钞护,當(dāng)控件內(nèi)容變化的時(shí)候使用LiveData進(jìn)行setValue或者postValue,也能達(dá)到爆办。

4.思考

學(xué)到這可以發(fā)現(xiàn)在MVVM难咕,是離不開(kāi)LiveData對(duì)于數(shù)據(jù)的訂閱的。但是對(duì)比前面學(xué)習(xí)的DataBinding距辆,兩者都可以實(shí)現(xiàn)雙向綁定余佃,而且網(wǎng)上很多文章都是將兩者共同使用的,所以我很想弄明白他們之前到底有什么優(yōu)劣跨算,所以才有下面的結(jié)論爆土。

4.1雙向綁定

使用viewmodel也可以通過(guò)livedata在數(shù)據(jù)訂閱回調(diào)中實(shí)現(xiàn)視圖的變化,數(shù)據(jù)更新視圖更新诸蚕。
但需要編寫(xiě)findViewById和set的過(guò)程步势,模塊一多代碼非常繁重,activity依然臃腫背犯。
使用viewmodel也可以通過(guò)livedata也可以通過(guò)setValue方法實(shí)現(xiàn)視圖更新引起數(shù)據(jù)更新坏瘩。
但一樣需要編寫(xiě)findViewById和控件監(jiān)聽(tīng)事件的過(guò)程,而且這樣會(huì)導(dǎo)致view需要去操作數(shù)據(jù)媳板。不符合MVVM的理念桑腮。
相較之下DataBinding實(shí)現(xiàn)非常簡(jiǎn)單,很多代碼都是自動(dòng)生成了在ActivityBindingImpl中蛉幸,代碼簡(jiǎn)潔破讨。
但DataBinding出現(xiàn)報(bào)錯(cuò)不容易定位和處理,對(duì)于新手而言不大友好奕纫。

4.2生命周期

DataBinding一樣可以使用ObservableField實(shí)現(xiàn)數(shù)據(jù)觀察提陶,但LiveData在數(shù)據(jù)對(duì)于組件生命周期的表現(xiàn)更加優(yōu)秀,且兼容更多匹层,是官方推薦的隙笆。

5.結(jié)論

MVVM模式的優(yōu)勢(shì)不言而喻锌蓄,而且由官方直接提供庫(kù),學(xué)了之后真的逃不過(guò)真香撑柔,組件的生命周期被監(jiān)聽(tīng)瘸爽,最大限度的避免內(nèi)存溢出甚至閃退。目前還感受不到MVVM在Android上的表現(xiàn)相較于傳統(tǒng)框架的大缺點(diǎn)铅忿〖艟觯可能比較弱勢(shì)的地方就是出現(xiàn)Bug的時(shí)候比較難定位,你無(wú)法得知出現(xiàn)問(wèn)題的是View層還是Model層檀训。

作者:陌過(guò)生人丶
鏈接:http://www.reibang.com/p/7fe5c2f9459a
來(lái)源:簡(jiǎn)書(shū)
著作權(quán)歸作者所有柑潦。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處峻凫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末渗鬼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子荧琼,更是在濱河造成了極大的恐慌譬胎,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铭腕,死亡現(xiàn)場(chǎng)離奇詭異银择,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)累舷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)夹孔,“玉大人被盈,你說(shuō)我怎么就攤上這事〈钌耍” “怎么了只怎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)怜俐。 經(jīng)常有香客問(wèn)我身堡,道長(zhǎng),這世上最難降的妖魔是什么拍鲤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任贴谎,我火速辦了婚禮,結(jié)果婚禮上季稳,老公的妹妹穿的比我還像新娘擅这。我一直安慰自己,他們只是感情好景鼠,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布仲翎。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪溯香。 梳的紋絲不亂的頭發(fā)上鲫构,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音玫坛,去河邊找鬼结笨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛昂秃,可吹牛的內(nèi)容都是我干的禀梳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼肠骆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼算途!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蚀腿,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤嘴瓤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后莉钙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體廓脆,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年磁玉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了停忿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蚊伞,死狀恐怖席赂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情时迫,我是刑警寧澤颅停,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站掠拳,受9級(jí)特大地震影響癞揉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜溺欧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一喊熟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧胧奔,春花似錦逊移、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拐叉。三九已至,卻和暖如春扇商,著一層夾襖步出監(jiān)牢的瞬間凤瘦,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工案铺, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔬芥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓控汉,卻偏偏與公主長(zhǎng)得像笔诵,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子姑子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345