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專(zhuān)注視圖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)存泄漏甚至崩潰。官方文檔中也有描述蛾茉。
lifecycle.jpg

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ì)象可觀(guān)察的。

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

但是更多的我們會(huì)使用LiveData常熙,LiveData能實(shí)現(xiàn)對(duì)象觀(guān)察纬乍,還可以感知組件生命周期,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方法队伟,即可觀(guān)察數(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專(zhuān)注于視圖的處理锈颗,而不是對(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的雙向綁定排宰,只需要activityMainBinding.setLifecycleOwner()即可似芝。一樣可以實(shí)現(xiàn)。


MVVM-toast.jpg

4.思考

學(xué)到這可以發(fā)現(xiàn)在MVVM板甘,是離不開(kāi)LiveData對(duì)于視圖數(shù)據(jù)的綁定的党瓮。但是對(duì)比前面學(xué)習(xí)的DataBinding,ObservableField都可以實(shí)現(xiàn)雙向綁定盐类。

4.1雙向綁定和生命周期

DataBinding可以使用ObservableField實(shí)現(xiàn)數(shù)據(jù)觀(guān)察寞奸,但LiveData通過(guò)activityMainBinding.setLifecycleOwner(this)也能實(shí)現(xiàn)雙向綁定。且LiveData在數(shù)據(jù)對(duì)于組件生命周期的表現(xiàn)更加優(yōu)秀在跳,且兼容更多類(lèi)型的數(shù)據(jù)枪萄,是官方推薦的。翻閱官方文章猫妙,發(fā)現(xiàn)需要我們這樣寫(xiě)瓷翻。
DataBinding+LiveData.jpg

5.結(jié)論

MVVM模式的優(yōu)勢(shì)不言而喻,而且由官方直接提供庫(kù)割坠,學(xué)了之后真的逃不過(guò)真香齐帚,MVVM+DataBinding+LiveData框架很強(qiáng)勢(shì)。組件的生命周期被監(jiān)聽(tīng)彼哼,最大限度的避免內(nèi)存溢出甚至閃退童谒。目前還感受不到MVVM在A(yíng)ndroid上的表現(xiàn)相較于傳統(tǒng)框架的大缺點(diǎn)』Ω幔可能比較弱勢(shì)的地方就是出現(xiàn)Bug的時(shí)候比較難定位饥伊,你無(wú)法得知出現(xiàn)問(wèn)題的是View層還是Model層。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蔫饰,一起剝皮案震驚了整個(gè)濱河市琅豆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌篓吁,老刑警劉巖茫因,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異杖剪,居然都是意外死亡冻押,警方通過(guò)查閱死者的電腦和手機(jī)驰贷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)洛巢,“玉大人括袒,你說(shuō)我怎么就攤上這事「遘裕” “怎么了锹锰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)漓库。 經(jīng)常有香客問(wèn)我恃慧,道長(zhǎng),這世上最難降的妖魔是什么渺蒿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任痢士,我火速辦了婚禮,結(jié)果婚禮上茂装,老公的妹妹穿的比我還像新娘怠蹂。我一直安慰自己,他們只是感情好训唱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著挚冤,像睡著了一般况增。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上训挡,一...
    開(kāi)封第一講書(shū)人閱讀 51,292評(píng)論 1 301
  • 那天澳骤,我揣著相機(jī)與錄音,去河邊找鬼澜薄。 笑死为肮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肤京。 我是一名探鬼主播颊艳,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忘分!你這毒婦竟也來(lái)了棋枕?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤妒峦,失蹤者是張志新(化名)和其女友劉穎重斑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體肯骇,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡窥浪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年祖很,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漾脂。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡假颇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出符相,到底是詐尸還是另有隱情拆融,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布啊终,位于F島的核電站镜豹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蓝牲。R本人自食惡果不足惜趟脂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望例衍。 院中可真熱鬧昔期,春花似錦、人聲如沸佛玄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)梦抢。三九已至般贼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奥吩,已是汗流浹背哼蛆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霞赫,地道東北人腮介。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像端衰,于是被迫代替她去往敵國(guó)和親叠洗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354