LiveData的基本使用 您所在的位置:网站首页 obey和observe LiveData的基本使用

LiveData的基本使用

#LiveData的基本使用| 来源: 网络整理| 查看: 265

我们在《ViewModel的基本使用》这篇文章中提到了,ViewModel的主要作用是存放页面所需要的各种数据,而当这些数据发生变化时,我们采用接口的方式实现对页面的通知。这样做是可行的,但如果要观察的数据很多,则需要定义大量的接口,代码显得冗余。为此,Android为我们提供了LiveData组件,帮助我们完成ViewModel与页面组件之间的通信。所以,LiveData通常是被放在ViewModel中使用

LiveData是一个可被观察的数据容器类。什么意思呢?我们可以将LiveData理解为一个数据的容器,它将数据包装起来,使得数据成为“被观察者”,页面成为“观察者”。这样,当该数据发生变化时,页面能够获得通知,进而更新UI。

进一步区别一下ViewModel和LiveData。ViewModel用于存放页面所需的各种数据,它还包括一些业务逻辑等,比如我们可以在ViewModel对数据进行加工,获取等操作。而对页面来说,它并不关心这些业务逻辑,它只关心需要展示的数据是什么,并且希望在数据发生变化时,能及时得到通知并做出更新。LiveData的作用就是,在ViewModel中的数据发生变化时通知页面。从LiveData(实时数据)这个名字,我们也能推测出,它的特性与作用。

我们来看看,如何在ViewModel中使用LiveData对数据进行包装。LiveData是一个抽象类,不能直接使用,所以通常我们使用它的直接子类MutableLiveData。

public class TimerWithLiveDataViewModel extends ViewModel { //将“秒钟”这个字段用MutableLiveData包装起来 private MutableLiveData currentSecond; public LiveData getCurrentSecond() { if (currentSecond == null) { currentSecond = new MutableLiveData(); } return currentSecond; } }

LiveData定义之后,如何利用它实现页面与ViewModel之间的通信呢?

public class TimerWithLiveDataActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_timer_with_live_data); iniComponent(); } private void iniComponent() { //通过ViewModelProviders得到ViewModel TimerWithLiveDataViewModel timerWithLiveDataViewModel = ViewModelProviders.of(this).get(TimerWithLiveDataViewModel.class); //得到ViewModel中的LiveData final MutableLiveData liveData = (MutableLiveData)timerWithLiveDataViewModel.getCurrentSecond(); //通过LiveData.observe()实现对ViewModel中数据变化的观察 liveData.observe(this, new Observer() { @Override public void onChanged(@Nullable Integer second) { //收到回调后更新UI界面 ((TextView)findViewById(R.id.tvTime)).setText("TIME:" + second); } }); findViewById(R.id.btnResetTime).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //通过LiveData.setValue()/LiveData.postValue()完成对ViewModel中数据的更新 liveData.setValue(0); } }); timerWithLiveDataViewModel.startTiming(); } }

在页面中,我们通过LiveData.observe()方法对LiveData包装的数据进行观察,反过来,当我们想要修改LiveData包装的数据时,可通过LiveData.postValue()/LiveData.setValue()来完成。postValue()是在非UI线程中使用,如果在UI线程中,则使用setValue()方法。

页面与LiveData之间的通信

让我们深入LiveData.observe()方法的源码。

@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) { if (owner.getLifecycle().getCurrentState() == DESTROYED) { // ignore return; } LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing != null && !existing.isAttachedTo(owner)) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } owner.getLifecycle().addObserver(wrapper); }

可以看到它接收的第一个参数是一个LifecycleOwner对象,在我们的示例中即Activity对象。第二个参数是一个Observer对象。通过最后一行代码将Observer与Activity的生命周期关联在一起。

owner.getLifecycle().addObserver(wrapper);

所以,LiveData能够感知页面的生命周期。它可以检测页面当前的状态是否为激活状态,或者页面是否被销毁。只有在页面处于激活状态(Lifecycle.State.ON_STARTED或Lifecycle.State.ON_RESUME)时,页面才会收到来自LiveData的通知,如果页面被销毁(Lifecycle.State.ON_DESTROY),那么LiveData会自动清除与页面的关联,从而避免了可能引发的内存泄漏问题。

LiveData还提供了一个observeForever()方法,使用起来与observe()没有太大差别,它们的区别主要在于,当LiveData包装的数据发生变化时,无论页面处于什么状态,observeForever()都能收到通知。所以,在使用完之后,一定要记得调用removeObserver()方法来停止对LiveData的观察,否则LiveData会一直处于激活状态,你的Activity永远不会被系统自动回收。

项目演示:



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有