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辱挥。