Is it possible to prevent LiveData receive the last value when start observing?
I am considering to use LiveData as events.
For example eve
Faced the same problem, and I created some simple kotlin extention functions which can solve the problem easily.
Usage as below:
val liveData = MutableLiveData()
liveData.value = "Hello"
val freshResult = mutableListOf()
val normalResult = mutableListOf()
liveData.observeForeverFreshly(Observer {
freshResult.add(it)
})
liveData.observeForever(Observer {
normalResult.add(it)
})
liveData.value = "World"
assertEquals(listOf("World"), freshResult)
assertEquals(listOf("Hello", "World"), normalResult)
Basic source code is explained as bllow.
For some more detail (to support some special situations for example MediatorLiveData returned from Transformations.map), you can view it in github : livedata-ext
FreshLiveData.kt
fun LiveData.observeFreshly(owner: LifecycleOwner, observer: Observer) {
// extention fuction to get LiveData's version, will explain in below.
val sinceVersion = this.version()
this.observe(owner, FreshObserver(observer, this, sinceVersion))
}
fun LiveData.observeForeverFreshly(observer: Observer, skipPendingValue: Boolean = true) {
val sinceVersion = this.version()
this.observeForever(FreshObserver(observer, this, sinceVersion))
}
// Removes the observer which has been previously observed by [observeFreshly] or [observeForeverFreshly].
fun LiveData.removeObserverFreshly(observer: Observer) {
this.removeObserver(FreshObserver(observer, this, 0))
}
class FreshObserver(
private val delegate: Observer,
private val liveData: LiveData<*>,
private val sinceVersion: Int
) : Observer {
override fun onChanged(t: T) {
if (liveData.version() > sinceVersion) {
delegate.onChanged(t)
}
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
if (delegate != (other as FreshObserver<*>).delegate) return false
return true
}
override fun hashCode(): Int {
return delegate.hashCode()
}
}
Becasue we need to access LiveData's pcakage visibile methond getVersion() for comparasion, so create a class in package android.arch.lifecycle or androidx.lifecycle (AndroidX):
LiveDataHiddenApi.kt
package androidx.lifecycle
fun LiveData<*>.version(): Int {
return this.getVersion()
}