[英]Navigation Component - Problem with Livedata lifecycle
我從導航組件開始,我在使用實時數據觀察器時遇到了一些問題。
例如:我有這個 livedata,它管理來自服務器的身份驗證響應。
viewModel.authenticate.observe(this, Observer {
manageAuthResponse(it)
})
一切正常,然后我轉到片段 B。但是當我在片段 B 中時,我嘗試返回片段 A(包含該實時數據), Observer
再次觸發,並顯示先前的結果 (SUCCESS)。
我怎樣才能防止這種情況?
當我回去時,我想刷新這個結果並防止 livedata 觀察者被解雇。
將您的 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)
}
}
}
然后在視圖模型中
val authenticate = MutableLiveData<Consumable<AuthenticationObject>>()
在你的片段中
viewModel.authenticate.observe(this, Observer { consumable ->
consumable.consume {
manageAuthResponse(it)
}
})
像這樣包裝 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
}
}
}
然后在 ViewModel
val viewModel = LiveEvent<Resource<String>>()
這個解決方案對我有用
你可以查看這個github中的代碼
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.