Android官方組件之ViewModel結(jié)合LiveData

LiveData的優(yōu)點(diǎn)

  • 不用手動(dòng)控制生命周期展父,當(dāng)數(shù)據(jù)變化它只會(huì)給前臺(tái)活動(dòng)的activity回調(diào)祸憋。
  • 不用擔(dān)心內(nèi)存泄露。
  • 如果一個(gè)觀察者處于 Paused 或 Destroyed。 狀態(tài),它將不會(huì)受到通知蝉稳,一旦觀察者重新恢復(fù) Resumed 狀態(tài),它將會(huì)收到 LiveData 的最新數(shù)據(jù)。

ViewModel的優(yōu)點(diǎn)

為Activity稠氮、Fragment存儲(chǔ)數(shù)據(jù),直到完全銷毀半开,不會(huì)發(fā)生試圖去刷新那些不存在的了View而出現(xiàn)空指針異常隔披。

引入

    def lifecycle_version = "1.1.1"
    // ViewModel and LiveData
    implementation "android.arch.lifecycle:extensions:$lifecycle_version"
    // alternatively - just ViewModel
    implementation "android.arch.lifecycle:viewmodel:$lifecycle_version"
    // alternatively - just LiveData
    implementation "android.arch.lifecycle:livedata:$lifecycle_version"

創(chuàng)建MutableLiveData

MutableLiveData是LiveData的子類,添加了公共方法setValue和postValue

public class UserViewModel extends ViewModel {
    public MutableLiveData<String> user = new MutableLiveData<>();
}

在Activity或者Fragment綁定

public class DemoActivity extends Activity {
    private UserViewModel userViewModel;
    private Button mBtn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
        ...
        userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
        userViewModel.user.observe(this, new Observer<String>() { //注冊(cè)觀察者
            @Override
            public void onChanged(String s) {
                Log.e(TAG, "onChanged: 監(jiān)聽(tīng)值有變化="+s);
            }
        });

        mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 改變值
                userViewModel.user.setValue("測(cè)試"); 
            }
        }
    }
}

API

1. postValue()

在子線程刷新數(shù)據(jù)寂拆。

2. setValue()

只能在主線程里調(diào)用奢米。

3. getValue()

返回當(dāng)前值。

4. observe

綁定觀察者, 會(huì)給此activity或者Fragment在前臺(tái)時(shí)回調(diào)數(shù)據(jù)(onStarted或者onResumed狀態(tài))纠永。

5. removeObserver(@NonNull final Observer<? super T> observer)

移除指定觀察者鬓长。

6. removeObservers(@NonNull final LifecycleOwner owner)

移除當(dāng)前Activity或者Fragment的全部觀察者。

mMainViewModel.getContent().removeObservers(this);

7. hasActiveObservers()

如果此LiveData具有活動(dòng)(Activity或者Fragment在前臺(tái),當(dāng)前屏幕顯示)的觀察者尝江,則返回true涉波。其實(shí)如果這個(gè)數(shù)據(jù)的觀察者在最前臺(tái)就返回true,否則false炭序。

8. hasObservers()

如果此LiveData具有觀察者啤覆,則返回true。

9. observeForever(@NonNull Observer<? super T> observer)

設(shè)置永遠(yuǎn)觀察者惭聂,永遠(yuǎn)不會(huì)被自動(dòng)刪除窗声。您需要手動(dòng)調(diào)用removeObserver(Observer)以停止觀察此LiveData,設(shè)置后此LiveData辜纲,一直處于活動(dòng)狀態(tài)笨觅,不管是否在前臺(tái)哪里都會(huì)獲得回調(diào)。

10. onActive()

在LiveData中侨歉,onActive方法回調(diào)表明當(dāng)前Activity處于激活狀態(tài)屋摇,也就是Activity處于生命周期的活動(dòng)狀態(tài)中(onStart,onResume)幽邓,可以簡(jiǎn)單認(rèn)為當(dāng)前的Activity處于前臺(tái)炮温。

11. onInactive()

LiveData的onInactive處理涉及onActive剩下的生命周期,可以簡(jiǎn)單理解onInactive是Android的Activity/Fragment處于未激活(后臺(tái)牵舵,比如當(dāng)前Activity處于生命周期的onStop柒啤,onPause)倦挂。

12. ViewModelProvider.of(@NonNull Fragment fragment, @Nullable Factory factory)

向ViewModel傳參。

public class TestViewModel extends ViewModel {

    private final String mKey;
    private MutableLiveData<String> mNameEvent = new MutableLiveData<>();

    public MutableLiveData<String> getNameEvent() {
        return mNameEvent;
    }

    public TestViewModel(String key) {
        mKey = key;
    }

    public static class Factory implements ViewModelProvider.Factory {
        private String mKey;

        public Factory(String key) {
            mKey = key;
        }

        @Override
        public <T extends ViewModel> T create(Class<T> modelClass) {
            return (T) new TestViewModel(mKey);
        }
    }

    public String getKey() {
        return mKey;
    }
}
ViewModelProviders.of(this, new TestViewModel.Factory(mkey)).get(TestViewModel.class)

使用場(chǎng)景

  • 當(dāng) config 導(dǎo)致 activity 重新創(chuàng)建的時(shí)候担巩,不需要手動(dòng)取處理數(shù)據(jù)的儲(chǔ)存和恢復(fù)方援。它已經(jīng)幫我們封裝好了。
  • 多個(gè)fragment同步數(shù)據(jù)涛癌。
  • 監(jiān)聽(tīng)網(wǎng)絡(luò)變化處理數(shù)據(jù)犯戏。
  • 在Activity處于不可見(jiàn)比如用戶按Home鍵不可見(jiàn)時(shí)候,此時(shí)可能不希望再做處理拳话,那么就可以在LiveData的onInactive做一個(gè)邏輯處理先匪,改變?nèi)蝿?wù)的狀態(tài),如果當(dāng)前Activity又被用戶調(diào)回前臺(tái)弃衍,那么可以在LiveData的onActive重新恢復(fù)任務(wù)的運(yùn)行呀非。

建議

  • ViewModel(和presenter)不要和Android Framework里的任何類發(fā)生關(guān)系。
  • ViewModel 不應(yīng)持有 View镜盯、Lifecycle岸裙、或其他可能持有 Activity 的 Context 的類的引用。
  • 其他類不應(yīng)持有 ViewModel 的引用速缆。在 Activity 或 Fragment 銷毀后降允,其它任何比 Activity 或 Fragment 生命周期長(zhǎng)的類都不應(yīng)再持有 ViewModel 的引用,否則會(huì)影響 ViewModel 被 GC 回收艺糜,從而泄露 ViewModel拟糕。
  • 用一個(gè)包裝類或者另一個(gè)LiveData來(lái)發(fā)出數(shù)據(jù)的狀態(tài),比如可以在ViewModel放出一個(gè)LiveData<MyDataState>. 例如, MyDataState 包含數(shù)據(jù)正在加載中倦踢,已經(jīng)成功加載或加載失敗了3種信息。
  • 要有效存取和恢復(fù)UI狀態(tài)侠草,組合使用persistence, onSaveInstanceState()和 ViewModels辱挥。

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市边涕,隨后出現(xiàn)的幾起案子晤碘,更是在濱河造成了極大的恐慌,老刑警劉巖功蜓,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件园爷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡式撼,警方通過(guò)查閱死者的電腦和手機(jī)童社,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)著隆,“玉大人扰楼,你說(shuō)我怎么就攤上這事呀癣。” “怎么了弦赖?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵项栏,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蹬竖,道長(zhǎng)沼沈,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任币厕,我火速辦了婚禮列另,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘劈榨。我一直安慰自己访递,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布同辣。 她就那樣靜靜地躺著拷姿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旱函。 梳的紋絲不亂的頭發(fā)上响巢,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音棒妨,去河邊找鬼踪古。 笑死,一個(gè)胖子當(dāng)著我的面吹牛券腔,可吹牛的內(nèi)容都是我干的伏穆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼纷纫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼枕扫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起辱魁,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤烟瞧,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后染簇,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體参滴,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年锻弓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了砾赔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖过蹂,靈堂內(nèi)的尸體忽然破棺而出十绑,到底是詐尸還是另有隱情,我是刑警寧澤酷勺,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布本橙,位于F島的核電站,受9級(jí)特大地震影響脆诉,放射性物質(zhì)發(fā)生泄漏甚亭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一击胜、第九天 我趴在偏房一處隱蔽的房頂上張望亏狰。 院中可真熱鬧,春花似錦偶摔、人聲如沸暇唾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)策州。三九已至,卻和暖如春宫仗,著一層夾襖步出監(jiān)牢的瞬間够挂,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工藕夫, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留孽糖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓毅贮,卻偏偏與公主長(zhǎng)得像办悟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滩褥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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

  • 懶得處理樣式了, 將就著看吧. 官網(wǎng)地址: https://developer.android.com/topic...
    Reddington_604e閱讀 1,659評(píng)論 0 1
  • 簡(jiǎn)評(píng):MVVM 是谷歌提出的一種 Android 架構(gòu)模式誉尖,結(jié)合了 Data Binding 和一些生命周期組件 ...
    云里霧花閱讀 1,953評(píng)論 0 3
  • ??LiveData是一個(gè)可被觀察的數(shù)據(jù)持有者類。與常規(guī)的Observable不同铸题,LiveData能意識(shí)到應(yīng)用程...
    鶴鶴閱讀 47,033評(píng)論 6 42
  • 每種下一顆種子丢间,都希望最后能收獲豐碩的果實(shí)。然而驹针,并不是所有的播種都會(huì)有收獲烘挫,所以等待的過(guò)程中會(huì)有猶豫,有焦...
    可樂(lè)zou閱讀 301評(píng)論 0 0
  • 總以為前面的路 還有很長(zhǎng) 可以放肆瘋狂 總以為青春的腳步 有你在場(chǎng) 可以劍拔弩張 從未在意 珍惜過(guò)往 翻閱昨日 卻...
    累成詩(shī)閱讀 122評(píng)論 0 0