为什么要引进 LiveData
LiveData 是一个可以被观察的数据持有类,它可以感知 Activity、Fragment或Service 等组件的生命周期。简单来说,他主要有一下优点。
它可以做到在组件处于激活状态的时候才会回调相应的方法,从而刷新相应的 UI。
不用担心发生内存泄漏
当 config 导致 activity 重新创建的时候,不需要手动取处理数据的储存和恢复。它已经帮我们封装好了。
当 Actiivty 不是处于激活状态的时候,如果你想 livedata setValue 之后立即回调 obsever 的 onChange 方法,而不是等到 Activity 处于激活状态的时候才回调 obsever 的 onChange 方法,你可以使用 observeForever 方法,但是你必须在 onDestroy 的时候 removeObserver。
回想一下,在你的项目中,是不是经常会碰到这样的问题,当网络请求结果回来的时候,你经常需要判断 Activity 或者 Fragment 是否已经 Destroy, 如果不是 destroy,才更新 UI。而当你如果使用 Livedata 的话,因为它是在 Activity 处于 onStart 或者 onResume 的状态时,他才会进行相应的回调,因而可以很好得处理这个问题,不必谢一大堆的 activity.isDestroyed()。接下来,让我们一起来看一下 LiveData 的使用
LiveData 使用
基本使用
引入相关的依赖包
// ViewModel and LiveData
implementation “android.arch.lifecycle:extensions:1.1.0”
// alternatively, just ViewModel
implementation “android.arch.lifecycle:viewmodel:1.1.0”
// alternatively, just LiveData
implementation “android.arch.lifecycle:livedata:1.1.0”
在代码中使用
LiveData 是一个抽象类,它的实现子类有 MutableLiveData ,MediatorLiveData。在实际使用中,用得比较多的是 MutableLiveData。他常常结合 ViewModel 一起使用。下面,让我们一起来看一下怎样使用它?
首先,我们先写一个类继承我们的 ViewModel,里面持有 mNameEvent。
public class TestViewModel extends ViewModel {
private MutableLiveData<String> mNameEvent = new MutableLiveData<>();
public MutableLiveData<String> getNameEvent() {
return mNameEvent;
}
}
接着,
我们在 Activity 中创建 ViewModel,并监听 ViewModel 里面 mNameEvent 数据的变化,当数据改变的时候,我们打印相应的 log,并设置给 textView,显示在界面上。这样我们就完成了对 mNameEvent 数据源的观察。
mTestViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
MutableLiveData<String> nameEvent = mTestViewModel.getNameEvent();
nameEvent.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
Log.i(TAG, "onChanged: s = " + s);
mTvName.setText(s);
}
});
最后当我们数据源改变的时候,我们需要调用 livedata 的 setValue 或者 postvalue 方法。他们之间的区别是, 调用 setValue 方法,Observer 的 onChanged 方法会在调用 serValue 方法的线程回调。而
postvalue 方法,Observer 的 onChanged 方法将会在主线程回调。
mTestViewModel.getNameEvent().setValue(name);
可能部分同学有这样的疑问了,我们的 ViewModel 是通过 ViewModelProviders.of(this).get(TestViewModel.class); 方法创建出来的,如果我们要携带参数,怎么办?
其实,官方也替我们考虑好了,同样是调用 ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) 方法,只不过,需要多传递一个 factory 参数。
Factory 是一个接口,它只有一个 create 方法。
public interface Factory