[英]Navigation Component - Problem with Livedata lifecycle
I'm beginning with navigation components and I'm facing some problem with a livedata observer.我从导航组件开始,我在使用实时数据观察器时遇到了一些问题。
For example: I have this livedata, who manage auth response from server.例如:我有这个 livedata,它管理来自服务器的身份验证响应。
viewModel.authenticate.observe(this, Observer {
manageAuthResponse(it)
})
Everything works fine, and I go to Fragment B. But when I'm in Fragment B, and I try to go back to Fragment A (who contains that livedata), the Observer
fires again with the previous result (SUCCESS).一切正常,然后我转到片段 B。但是当我在片段 B 中时,我尝试返回片段 A(包含该实时数据),
Observer
再次触发,并显示先前的结果 (SUCCESS)。
How can I prevent this?我怎样才能防止这种情况?
When I go back, I want to refresh this result and prevent livedata observer to be fired.当我回去时,我想刷新这个结果并防止 livedata 观察者被解雇。
Wrap your LiveData object in a ConsumableValue
like this将您的 LiveData 对象包装在这样的
ConsumableValue
class ConsumableValue<T>(private val data: T) {
private var consumed = false
fun consume(block: ConsumableValue<T>.(T) -> Unit) {
if (!consumed) {
consumed = true
block(data)
}
}
}
then in viewmodel然后在视图模型中
val authenticate = MutableLiveData<Consumable<AuthenticationObject>>()
and in your fragment在你的片段中
viewModel.authenticate.observe(this, Observer { consumable ->
consumable.consume {
manageAuthResponse(it)
}
})
Wrap the LiveDate Like this像这样包装 LiveDate
open class LiveEvent<T> : MediatorLiveData<T>() {
private val observers = ArraySet<ObserverWrapper<in T>>()
@MainThread
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
val wrapper = ObserverWrapper(observer)
observers.add(wrapper)
super.observe(owner, wrapper)
}
@MainThread
override fun observeForever(observer: Observer<in T>) {
val wrapper = ObserverWrapper(observer)
observers.add(wrapper)
super.observeForever(wrapper)
}
@MainThread
override fun removeObserver(observer: Observer<in T>) {
if (observers.remove(observer)) {
super.removeObserver(observer)
return
}
val iterator = observers.iterator()
while (iterator.hasNext()) {
val wrapper = iterator.next()
if (wrapper.observer == observer) {
iterator.remove()
super.removeObserver(wrapper)
break
}
}
}
@MainThread
override fun setValue(t: T?) {
observers.forEach { it.newValue() }
super.setValue(t)
}
private class ObserverWrapper<T>(val observer: Observer<T>) : Observer<T> {
private var pending = false
override fun onChanged(t: T?) {
if (pending) {
pending = false
observer.onChanged(t)
}
}
fun newValue() {
pending = true
}
}
}
then in ViewModel然后在 ViewModel
val viewModel = LiveEvent<Resource<String>>()
This solution is work for me这个解决方案对我有用
You can check out the code in this github你可以查看这个github中的代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.