livedata-ktx
livedata-ktx copied to clipboard
PublishLiveDataKtx not remove observer by lifecycle event
Code from https://github.com/Shopify/livedata-ktx/blob/master/livedata-ktx/src/main/java/com/shopify/livedataktx/PublishLiveDataKtx.kt:
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
val observeSinceVersion = version
val wrapper = observerWrappers.getOrElse(observer, Observer {
if (!isPublish || version > observeSinceVersion) {
observer.onChanged(it)
}
})
observerWrappers.putIfAbsent(observer, wrapper)
super.observe(owner, wrapper)
}
override fun observeForever(observer: Observer<in T>) {
val observeSinceVersion = version
val wrapper = observerWrappers.getOrElse(observer, Observer {
if (!isPublish || version > observeSinceVersion) {
observer.onChanged(it)
}
})
observerWrappers.putIfAbsent(observer, wrapper)
super.observeForever(wrapper)
}
override fun removeObserver(observer: Observer<in T>) {
observerWrappers.get(observer)?.let { super.removeObserver(it) }
observerWrappers.removeIfPresent(observer)
}
When we call observeForever(), all looks good and calling removeObserver() with same Observer working as expected.
But if we call observe() and later lifecycle move to Destroyed state, system call removeObserver() with wrapped Observer, and we try to find it in observedWrappers among non-wrapped observers. Pair instances with weak references to observers just accumulated in array until livedata instance not GCed.
I don't know clear solution of this problem, suppose we can check wrapped and non-wrapped observers both when removing.