Android LiveData阻止在观察时收到最后一个值 [英] Android LiveData prevent receive the last value on observe
问题描述
是否可以防止LiveData
在开始观察时接收到最后一个值?
我正在考虑使用LiveData
作为事件.
Is it possible to prevent LiveData
receive the last value when start observing?
I am considering to use LiveData
as events.
例如类似于EventBus
的显示消息,导航事件或对话框触发器之类的事件.
For example events like show message, a navigation event or a dialog trigger, similar to EventBus
.
与ViewModel
和fragment之间的通信有关的问题,Google给了我们LiveData
用数据更新视图,但是这种类型的通信不适用于我们仅需要通过单个事件更新一次视图的情况,因此我们无法在ViewModel
中保存视图的引用并调用一些方法,因为这会导致内存泄漏.
The problem related to communication between ViewModel
and fragment, Google gave us LiveData
to update the view with data, but this type of communication not suitable when we need update the view only once with single event, also we cannot hold view's reference in ViewModel
and call some methods because it will create memory leak.
I found something similar SingleLiveEvent - but it work only for 1 observer and not for multiple observers.
---更新----
@EpicPandaForce说"没有理由将LiveData用作不是它的东西",问题的意图可能是
As @EpicPandaForce said "There is no reason to use LiveData as something that it is not", probably the intent of the question was Communication between view and ViewModel in MVVM with LiveData
推荐答案
没有理由将LiveData用作不是.如果您需要单独的行为(某种东西不会保留以前的值),那么您应该使用一个不能保留以前的值的组件-而不是乱砍它(记住"它已经发出并忘记了)发射等等)
There is no reason to use LiveData as something that it is not. If you need a separate behavior (something that doesn't retain the previous value), then you should use a component that doesn't retain the previous value -- instead of hacking around it ("remembering" that it had emitted and then forgetting to emit, etc.)
您可以添加event-emitter
库:
implementation 'com.github.Zhuinden:event-emitter:1.1.0'
来自Jitpack:maven { url "https://jitpack.io" }
from Jitpack: maven { url "https://jitpack.io" }
那你就可以做
// read
private var subscription: EventSource.NotificationToken? = null
fun observe() {
subscription = events.startListening { event ->
showToast(event)
}
}
fun unsubscribe() {
subscription?.stopListening()
subscription = null
}
但是如果您需要像这样使用它:
But if you need to use it like this:
controllerEvents.observe(viewLifecycleOwner) { event: WordController.Events ->
when (event) {
is WordController.Events.NewWordAdded -> showToast("Added ${event.word}")
}.safe()
}
然后您就可以使用
import android.arch.lifecycle.Lifecycle
import android.arch.lifecycle.LifecycleObserver
import android.arch.lifecycle.LifecycleOwner
import android.arch.lifecycle.OnLifecycleEvent
import com.zhuinden.eventemitter.EventSource
private class LiveEvent<T> constructor(
private val eventSource: EventSource<T>,
private val lifecycleOwner: LifecycleOwner,
private val observer: EventSource.EventObserver<T>
) : LifecycleObserver {
init {
if (lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) {
lifecycleOwner.lifecycle.addObserver(this)
}
}
private var isActive: Boolean = false
private var notificationToken: EventSource.NotificationToken? = null
private fun shouldBeActive(): Boolean {
return lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)
}
private fun disposeObserver() {
lifecycleOwner.lifecycle.removeObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
if (lifecycleOwner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
stopListening()
disposeObserver()
return
}
checkIfActiveStateChanged(shouldBeActive())
}
private fun checkIfActiveStateChanged(newActive: Boolean) {
if (newActive == isActive) {
return
}
val wasActive = isActive
isActive = newActive
val isActive = isActive
if (!wasActive && isActive) {
stopListening()
notificationToken = eventSource.startListening(observer)
}
if (wasActive && !isActive) {
stopListening()
}
}
private fun stopListening() {
notificationToken?.stopListening()
notificationToken = null
}
}
fun <T> EventSource<T>.observe(lifecycleOwner: LifecycleOwner, eventObserver: (T) -> Unit) {
LiveEvent(this, lifecycleOwner, EventSource.EventObserver<T> { event -> eventObserver.invoke(event) })
}
这篇关于Android LiveData阻止在观察时收到最后一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!