Jetpack -- ViewModel

前言
前幾篇文章介紹了Jetpack及其LiveData冰肴,越發(fā)的發(fā)現(xiàn)Jetpack在Android開發(fā)中地位勢不可擋茶袒,在Android developers官網(wǎng)已經(jīng)將Jetpack放在頂部一級列表餐抢,不學(xué)習(xí)點Jetpack怎么好意思是做Android開發(fā)的。
Jetpack分四類玲献,基礎(chǔ)廓啊、架構(gòu)、行為乾胶、界面抖剿,今天學(xué)習(xí)的架構(gòu)的中的 ViewModel,他和LiveData配合使用可以吊炸天识窿。還不懂LiveData的同仁斩郎,請看先看Jetpack -- LiveData

一. ViewModel概述
ViewModel是Lifecycle中的一個組件喻频,旨在以注重生命周期的方式存儲和管理界面相關(guān)的數(shù)據(jù)缩宜。讓界面數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)后繼續(xù)存在。Android中的控制器(activity和fragment)銷毀或者重建會丟失數(shù)據(jù)甥温,現(xiàn)在把數(shù)據(jù)存儲在ViewModel锻煌,不會受到控制器的銷毀或者重建而丟失數(shù)據(jù)。

二.ViewModel能解決什么問題

  1. 解決數(shù)據(jù)丟失問題


    untitled.png

    上圖是官網(wǎng)給出的姻蚓,展示了屏幕旋轉(zhuǎn)activity的生命周期宋梧,但是ViewModel一直存在,直到activity銷毀才調(diào)用了清除方法onCleared()捂龄。
    顯然,viewModel是最好保存數(shù)據(jù)的方式加叁。在沒有ViewModel之前,遇到屏幕切換保存數(shù)據(jù)使用onSaveInstanceState殉农,但是onSaveInstanceState只能保存輕量級數(shù)據(jù)刀脏,大點的數(shù)據(jù)是無法保存的超凳。ViewModel解決了我們這個痛點愈污。

  2. fragment之間數(shù)據(jù)共享
    Activity 中的兩個或更多 Fragment 需要相互通信是一種很常見的情況。在以前我們是通過接口回調(diào)實現(xiàn)fragment之間通信轮傍,統(tǒng)一在activity中管理暂雹。有一種情況,一個fragment包含了另一個fragment创夜,也就是一個fragment持有了另一個fragment的引用杭跪。這樣最后的結(jié)果,耦合度太高涧尿,還需要大量的工作系奉,官方給出了代碼示例:

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }

    public LiveData<Item> getSelected() {
        return selected;
    }
}


public class MasterFragment extends Fragment {
    private SharedViewModel model;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends Fragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        model.getSelected().observe(this, { item ->
           // Update the UI.
        });
    }
}

這么寫的好處是:
①Activity 不需要做任何事姑廉,甚至不知道這次交互缺亮,完美解耦。
②Fragment 僅僅與ViewModel交互桥言,不需要知道其他Fragment 的狀態(tài)甚至是否存在萌踱,更不需要持有其引用。所有當(dāng)對方 Fragment 銷毀時号阿,不影響本身任何工作并鸵。
③Fragment 生命周期互不影響,甚至 fragment 替換成其他的 也不影響這個系統(tǒng)的運作扔涧。

  1. 解決異步回調(diào)等待結(jié)果問題
    App中有好多網(wǎng)絡(luò)請求的工作,這個工作都是耗時的的枯夜,而且一般都是放在控制器(如activity或者fragment)處理,所以必須放在子線程做異步操作卤档,否則會引起ANR。有時候還有控制器已經(jīng)銷毀后才會獲取到網(wǎng)絡(luò)數(shù)據(jù)劝枣,這樣導(dǎo)致內(nèi)存泄漏甚至OOM。如果使用ViewModel就會完美解決此痛點织鲸。

  2. 減輕UI層負(fù)擔(dān)
    控制器(如activity或者fragment)作用是用來展示數(shù)據(jù)、響應(yīng)用戶行為搂擦、處理事件的稳诚。而平時我們會把網(wǎng)絡(luò)或數(shù)據(jù)庫數(shù)據(jù)交給他們瀑踢,會讓其顯得臃腫切難以管理扳还。
    從MVC 到MVP橱夭、MVVM氨距,目的是 明確職責(zé),分離控制器負(fù)擔(dān)俏让。我們現(xiàn)在可以把數(shù)據(jù)操作的工作交給 ViewModel。

三.ViewModel具體實現(xiàn)
先看簡單的效果,點踩減一寡喝,點贊加一。

image.png

  1. 自定義Viewmodel繼承ViewModel预鬓,管理一個整型數(shù)據(jù)
/**
 * 只管理一個變量number
 */
public class AnflyViewModel extends ViewModel {
    public int number = 0;
}
  1. 在MainActivity獲取ViewModel對象,就可以對數(shù)據(jù)進行操作
//獲取Viewmodel實例
anflyViewModel = ViewModelProviders.of(this).get(AnflyViewModel.class);
//重新創(chuàng)建activity是不會丟失數(shù)據(jù)(橫豎屏切換)
tv_number.setText(String.valueOf(anflyViewModel.number));

3.點擊踩和贊使用ViewModel操作數(shù)據(jù)撬陵,MainActivity負(fù)責(zé)更新UI

    @Override
    public void onClick(View v) {
        //使用ViewModel操作數(shù)據(jù)
        switch (v.getId()) {
            case R.id.iv_dislike:
                anflyViewModel.number--;
                break;
            case R.id.iv_like:
                anflyViewModel.number++;
                break;
        }
        //MainActivity負(fù)責(zé)更新UI 
        tv_number.setText(String.valueOf(anflyViewModel.number));
    }

四.ViewModel實現(xiàn)原理
后續(xù)文章逐漸退出

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市巨税,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌草添,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件远寸,死亡現(xiàn)場離奇詭異抄淑,居然都是意外死亡驰后,警方通過查閱死者的電腦和手機肆资,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門灶芝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人夜涕,你說我怎么就攤上這事犯犁。” “怎么了女器?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵酸役,是天一觀的道長驾胆。 經(jīng)常有香客問我涣澡,道長,這世上最難降的妖魔是什么暑塑? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮事格,結(jié)果婚禮上惕艳,老公的妹妹穿的比我還像新娘。我一直安慰自己远搪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布逢捺。 她就那樣靜靜地躺著谁鳍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劫瞳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天志于,我揣著相機與錄音,去河邊找鬼伺绽。 笑死养泡,一個胖子當(dāng)著我的面吹牛奈应,可吹牛的內(nèi)容都是我干的澜掩。 我是一名探鬼主播杖挣,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肩榕,長吁一口氣:“原來是場噩夢啊……” “哼惩妇!你這毒婦竟也來了点把?” 一聲冷哼從身側(cè)響起贮尖,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤碗殷,失蹤者是張志新(化名)和其女友劉穎挺份,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贮懈,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年各聘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抡医。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡早敬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出大脉,到底是詐尸還是另有隱情搞监,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布琐驴,位于F島的核電站,受9級特大地震影響秤标,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜苍姜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怖现。 院中可真熱鬧茁帽,春花似錦屈嗤、人聲如沸潘拨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至琅束,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間算谈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工然眼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人高每。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓屿岂,卻偏偏與公主長得像鲸匿,于是被迫代替她去往敵國和親爷怀。 傳聞我的和親對象是個殘疾皇子带欢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

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