一、前言
ViewModel 可觀察數(shù)據(jù)存儲類屬于谷歌在2018推出Android jetpack(外網(wǎng))其中的軟件架構(gòu)組件中的一個。在谷歌開發(fā)者網(wǎng)站有詳細(xì)介紹ViewModel(外網(wǎng))。
全文就一句話
ViewModel核心:存儲和管理界面相關(guān)的數(shù)據(jù)
理解此文前建議簡單閱讀Lifecycle,理解生命周期組件
二、ViewModel
谷歌爸爸介紹
ViewModel類旨在以注重生命周期的方式存儲和管理界面相關(guān)的數(shù)據(jù)。ViewModel類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)存在。
ViewModel使用場景
ViewModel的使用主要是獨立存儲和管理界面相關(guān)的數(shù)據(jù),把界面數(shù)據(jù)分離出來用ViewModel來管理。
比如Activity/Fragment要重復(fù)的打開關(guān)閉,若數(shù)據(jù)時一些網(wǎng)絡(luò)請求什么的,不必每次創(chuàng)建都去異步請求,請求一次,ViewModel統(tǒng)一管理就好。
為什么例子中的ViewModel都是管理LiveData
ViewModel管理的數(shù)據(jù)可以是多種,只不過我們更多的管理LiveData,因為LiveData有觀察者模式+生命周期特性,方便數(shù)據(jù)變化時去改變界面。所以他們形影不離。
因為你的目的就是數(shù)據(jù)變化了去更改UI,如果不用LiveData,就普通的一個String,你得加個回調(diào)監(jiān)聽或者別的方式通知到UI你數(shù)據(jù)已經(jīng)變化了,你得判斷空,判斷context是否還存在,等等。思想上他們是相同的。
三、詳細(xì)介紹
ViewModel總結(jié)來就是下面
- 1、生命周期
- 2、Fragment間共享數(shù)據(jù)
- 3、使用場景
3.1、生命周期
ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication());
ViewModelProvider viewModelProvider = new ViewModelProvider(this, factory);
viewModel = viewModelProvider.get(MyViewModel.class);
- ViewModel創(chuàng)建是:傳遞給ViewModelProvider一個Lifecycle(代碼中的this)+工廠模式來創(chuàng)建
- ViewModel創(chuàng)建后隨著Lifecycle一起一直存在,直到Lifecycle消失,即Activity/Fragement銷毀(銷毀時,Lifecycle消失)。
-
ViewModel完全依賴于Lifecycle的,所以ViewModel具有生命周期感知能力
來看谷歌爸爸貼出來的一張圖
生命周期
3.2、Fragment共享數(shù)據(jù)
我們經(jīng)常在一個Activity寫多個Fragment,他們之間經(jīng)常切換共享數(shù)據(jù)。使用ViewModel就很方便。
public class MyViewModel extends ViewModel {
MutableLiveData<String> title;
public MutableLiveData<String> getTitle() {
return title;
}
}
public class MasterFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication());
ViewModelProvider viewModelProvider = new ViewModelProvider(getActivity(), factory);
viewModel = viewModelProvider.get(MyViewModel.class);
}
}
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewModelProvider.Factory factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication());
ViewModelProvider viewModelProvider = new ViewModelProvider(getActivity(), factory);
viewModel = viewModelProvider.get(MyViewModel.class);
}
}
- 在Activity范圍下,ViewModel拿到的對象實例是同一個。所以他們很方便的就能共享數(shù)據(jù),而不需要我們?nèi)ゲ僮鰽ctivity
- 各個Fragment之間沒有影響,一個關(guān)閉不會影響另一個
- 我們拿到數(shù)據(jù)也快,開啟一個新的Fragment,ViewModel沒有被銷毀,拿到實例就可顯示
3.3、應(yīng)用場景
- ViewModel + LiveData 管理UI數(shù)據(jù)
- Fragment之間共享數(shù)據(jù)
- VIewModel + LiveData+Room 數(shù)據(jù)加載器
- ViewModel + LiveData + DataBinding 綁定數(shù)據(jù)自動更新
分別說下這幾個控件
Lifecycle:設(shè)計來獨立生命周期。ViewModel和LiveData都依賴于Lifecycle,具有生命周期感知能力(本文ViewModel的體現(xiàn)就是一直存在直到Lifecycle銷毀)。依賴它就可以不必?fù)?dān)心生命周期存在否,UI是否顯示,Activity是否在后臺等邏輯。
ViewModel:它思想就是獨立管理數(shù)據(jù)。把這個數(shù)據(jù)管理任務(wù)和UI分離
LiveData:存在的目的是,既然ViewModel可以很好的拆分UI和數(shù)據(jù)了,那么就需要LiveData的來優(yōu)雅的更新UI,采用LiveData去更新UI,省去很多代碼和邏輯耦合。
DataBinding:布局引用數(shù)據(jù)源,簡化數(shù)據(jù)和UI之間的操作
Room:設(shè)計來輕量化管理sqlite,讓我們更好的操作。強大且穩(wěn)健。并且Room擴展返回LiveData或者Rxjava中的Publisher和Flowable或者cursor等
四、寫在最后
- 整體來說ViewModel還是十分簡單的一個控件。它被設(shè)計來存儲和管理界面相關(guān)的數(shù)據(jù)。
- 它也是一個比較基本的控件單元,多和一些別的控件一起使用。
- 巧妙的解耦和生命周期感知能力讓它簡單而又強大。
