Android之MVVM架構(gòu)指南(五):ViewModel

ViewModel 是Android 架構(gòu)組件中負(fù)責(zé)管理UI相關(guān)數(shù)據(jù)與邏輯的,它的功能定義與MVP架構(gòu)中的Persenter十分相似,配合其他組件使用增加許多方便開發(fā)的功能。

基本使用

定義一個ViewModel只需要繼承ViewModel抽象類即可:

public class MainViewModel extends ViewModel {
   
}

然后我們就可以在activity/fragment中實例化它:

MainViewModel viewModel = ViewModelProviders.of(this).get(MainViewModel.class);

注意:如果想要正常使用ViewModel的全部功能,不能直接new出ViewModel的實例,而是使用ViewModelProvider類創(chuàng)建,上面的ViewModelProviders其實就是對ViewModelProvider的包裝類。

正是因為通過ViewModelProvider創(chuàng)建ViewModel的方式,ViewModel才具備了一些比較方便實用的功能。

生命周期

因為創(chuàng)建ViewModel時傳入了activity/fragment對象實例(ViewModelProviders.of(this)),所以ViewModel可以感知宿主的生命周期。

當(dāng)宿主onDestroy()時候ViewModel便會自行銷毀掉,除此之前,當(dāng)屏幕旋轉(zhuǎn)的時候,Activity會被recreate,Activity會經(jīng)過幾個生命周期方法,但是這個時候ViewModel還是之前的對象,并沒有被重新創(chuàng)建。

共享數(shù)據(jù)

public class MainViewModel extends ViewModel{

}

public class Fragment1 extends Fragment{
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MainViewModel ViewModel = ViewModelProviders.of(getActivity()).get(MainViewModel.class);
    }
}

public class Fragment2 extends Fragment{
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MainViewModel ViewModel = ViewModelProviders.of(getActivity()).get(MainViewModel.class);
    }
}

上面的例子中,如果fragment1和fragment2的宿主activity是同一個的話,那么它們創(chuàng)建的ViewModel是同一個,ViewModel中的數(shù)據(jù)二者可以共享。

更新UI

ViewModel配合LiveData使用可以做到在不持有activity任何引用的情況下更新UI數(shù)據(jù),這是整個組件架構(gòu)中最有亮點以及最有特色的地方。

public class MainViewModel extends ViewModel{
    MutableLiveData<String> data = new MutableLiveData<>();

    public LiveData<String> getData(){
        return data;
    }

    public void loadData(){
        // 模擬一個數(shù)據(jù)請求
        data.setValue("test");
    }

}

public class Fragment1 extends Fragment{
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MainViewModel ViewModel = ViewModelProviders.of(this).get(MainViewModel.class);
        ViewModel.getData().observe(this,new Observer(){
            @Override
            public void onChanged(String s){
                textView.setText(s);
            }
        });
    }
}

在上面的例子中,textView會根據(jù)數(shù)據(jù)源的變化更新自己,而ViewModel中不需要考慮UI更新的問題,只需要關(guān)注數(shù)據(jù)的變化即可。

注意事項

ViewModel看似使用簡單,但是在實際使用中會有一些點需要關(guān)注的。

1. 數(shù)據(jù)源的初始化

ViewModel本質(zhì)上就是管理各種LiveData數(shù)據(jù)源的,但一定要注意的是在外界getData()前一定要初始化數(shù)據(jù)源,因為外界獲得數(shù)據(jù)源后一般會直接注冊觀察者,如果這時候數(shù)據(jù)源沒有初始化就會空指針異常。

2. 數(shù)據(jù)源的更新

上面的例子中loadData()方法更新數(shù)據(jù)源是直接用當(dāng)前data對象更新的,但是在實際使用中每次請求數(shù)據(jù)后極有可能會發(fā)生數(shù)據(jù)請求模塊返回一個新的LiveData實例,這種情況不能直接將當(dāng)前的data重新賦值:

data = newData;

這樣寫的話外界設(shè)置的觀察者就會失效了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容