如何清除LiveData的存储值? [英] How to clear LiveData stored value?

查看:1900
本文介绍了如何清除LiveData的存储值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 LiveData文档:

LiveData类具有以下优点:

The LiveData class provides the following advantages:

...

始终最新的数据::如果生命周期再次开始(例如活动从后堆栈返回到开始状态),它将收到最新的位置数据(如果还没有).

Always up to date data: If a Lifecycle starts again (like an activity going back to started state from the back stack) it receives the latest location data (if it didn’t already).

但是有时候我不需要此功能.

But sometimes I don't need this feature.

例如,我在ViewModel中有LiveData,在Activity中有Observer:

For example, I have following LiveData in ViewModel and Observer in Activity:

//LiveData
val showDialogLiveData = MutableLiveData<String>()

//Activity
viewModel.showMessageLiveData.observe(this, android.arch.lifecycle.Observer { message ->
        AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK") { _, _ -> }
                .show()
    })

现在,每旋转一次,就会出现一个旧对话框.

Now after every rotation old dialog will appear.

在处理完存储值之后是否有清除存储值的方法,或者根本是对LiveData的错误使用?

Is there a way to clear stored value after it's handled or is it wrong usage of LiveData at all?

推荐答案

更新

实际上,有几种方法可以解决此问题.在带有SnackBar,导航和其他事件(SingleLiveEvent案例)的LiveData .这是由与架构组件团队合作的Google同事撰写的.

Update

There are actually a few ways to resolve this issue. They are summarized nicely in the article LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case). This is written by a fellow Googler who works with the Architecture Components team.

TL; DR 一种更可靠的方法是使用事件包装器类,您可以在

TL;DR A more robust approach is to use an Event wrapper class, which you can see an example of at the bottom of the article.

此模式已将其引入众多Android示例中,例如:

This pattern has made it's way into numerous Android samples, for example:

  • Plaid
  • Architecture Blueprints
  • IOSched

为什么与SingleLiveEvent相比首选事件包装?

SingleLiveEvent的一个问题是,如果SingleLiveEvent有多个观察者,则在数据更改时将仅通知其中一个观察者-这可能会引入细微的错误,并且很难解决.

One issue with SingleLiveEvent is that if there are multiple observers to a SingleLiveEvent, only one of them will be notified when that data has changed - this can introduce subtle bugs and is hard to work around.

使用事件包装器类,将正常通知所有观察者.然后,您可以选择显式处理"内容(仅对内容进行处理"一次)或查看内容,该内容始终返回最新的内容".在对话框示例中,这意味着您始终可以使用peek查看最后一条消息,但是请确保对于每个新消息,使用getContentIfNotHandled仅触发一次对话框.

Using an Event wrapper class, all of your observers will be notified as normal. You can then choose to either explicitly "handle" the content (content is only "handled" once) or peek at the content, which always returns whatever the latest "content" was. In the dialog example, this means you can always see what the last message was with peek, but ensure that for every new message, the dialog only is triggered once, using getContentIfNotHandled.

亚历克斯在评论中的回答是,我认为正是您要找的东西.有一个名为

Alex's response in the comments is I think exactly what you're looking for. There's sample code for a class called SingleLiveEvent. The purpose of this class is described as:

可感知生命周期的可观察对象,仅在之后发送新更新 订阅,用于导航和Snackbar消息之类的事件.

A lifecycle-aware observable that sends only new updates after subscription, used for events like navigation and Snackbar messages.

这避免了事件的常见问题:更改配置时 (例如旋转),如果观察者处于活动状态,则可以发出更新. 仅当显式调用以下内容时,此LiveData才会调用可观察对象 setValue()或call().

This avoids a common problem with events: on configuration change (like rotation) an update can be emitted if the observer is active. This LiveData only calls the observable if there's an explicit call to setValue() or call().

这篇关于如何清除LiveData的存储值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆