ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android – 未观察到多次调用设置LiveData

2019-06-27 11:10:53  阅读:567  来源: 互联网

标签:android viewmodel kotlin android-livedata


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

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

以下是审核的代码段.

MainActivity.kt

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.

解决方法:

我做了一些科学研究,重新实现了LiveData和MutableLiveData来注销一些数据.

检查source code here.

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

当您发送初始值时,看起来观察者还没有达到活动状态.

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;
    }

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

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);
    }
}

标签:android,viewmodel,kotlin,android-livedata
来源: https://codeday.me/bug/20190627/1304187.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有