未观察到多次调用以设置LiveData [英] Multiple calls to set LiveData is not observed

查看:263
本文介绍了未观察到多次调用以设置LiveData的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近看到了一个奇怪的问题,它正在阻碍我的项目. 多次调用以设置实时数据值不会调用视图中的观察者.

I have recently seen a weird issue that is acting as a barrier to my project. Multiple calls to set the live data value does not invoke the observer in the view.

似乎只有最后设置的值才实际调用视图中的Observer.

It seems that only the last value that was set actually invokes the Observer in the view.

这是评论的代码段.

class MainActivity : AppCompatActivity() {

    private lateinit var viewModel: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel = ViewModelProviders.of(this).get(MainViewModelImpl::class.java)

        viewModel.state().observe(this, Observer {
            onStateChange(it!!)
        })

        viewModel.fetchFirstThree()

    }

    private fun onStateChange(state: MainViewModel.State) {

        when (state) {
            is One -> {
                show(state.data)
            }
            is Two -> {
                show(state.data)
            }
            is Three -> {
                show(state.data)
            }
        }
    }

    private fun show(data: String) {
        Log.d("Response", data)
    }
}

MainViewModel.kt

abstract class MainViewModel : ViewModel() {

    sealed class State {
        data class One(val data: String) : State()
        data class Two(val data: String) : State()
        data class Three(val data: String) : State()
    }

    abstract fun state(): LiveData<State>

    abstract fun fetchFirstThree()
}

MainViewModelImpl.kt

class MainViewModelImpl : MainViewModel() {

    private val stateLiveData: MediatorLiveData<State> = MediatorLiveData()

    override fun state(): LiveData<State> = stateLiveData

    override fun fetchFirstThree() {
        stateLiveData.value = State.One("One")
        stateLiveData.value = State.Two("Two")
        stateLiveData.value = State.Three("Three")
    }
}

预期输出:

Response: One
Response: Two
Response: Three

实际输出:

Response: Three

根据上面的输出,前两个值未调用Observer.

As per the output above, the Observer is not being called for the first two values.

推荐答案

我做了一些科学工作,重新实现了LiveData和MutableLiveData以注销一些数据.

I did some science, re-implementing LiveData and MutableLiveData to log out some data.

检查此处的源代码.

setValue value=Test1
dispatchingValue mDispatchingValue=false mDispatchInvalidated=false
considerNotify
Returned at !observer.active
setValue value=Test2
dispatchingValue mDispatchingValue=false mDispatchInvalidated=false
considerNotify
Returned at !observer.active
setValue value=Test3
dispatchingValue mDispatchingValue=false mDispatchInvalidated=false
considerNotify
Returned at !observer.active
dispatchingValue mDispatchingValue=false mDispatchInvalidated=false
considerNotify
ITEM: Test3

当您发送初始值时,观察者似乎尚未达到活动状态.

It looks like the observer hasn't reached an active state when you send the initial values.

private void considerNotify(LifecycleBoundObserver observer) {
    // <-- Three times it fails here. This means that your observer wasn't ready for any of them.
    if (!observer.active) {
        return;
    }

一旦观察者达到活动状态,它将发送最后一个设置值.

Once the observer reaches an active state, it sends the last set value.

void activeStateChanged(boolean newActive) {
    if (newActive == active) {
        return;
    }
    active = newActive;
    boolean wasInactive = LiveData.this.mActiveCount == 0;
    LiveData.this.mActiveCount += active ? 1 : -1;
    if (wasInactive && active) {
        onActive();
    }
    if (LiveData.this.mActiveCount == 0 && !active) {
        onInactive();
    }
    if (active) {
        // <--- At this point you are getting a call to your observer!
        dispatchingValue(this);
    }
}

这篇关于未观察到多次调用以设置LiveData的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆