多次调用时会忽略实时数据设置值

问题描述 投票:0回答:1

以下代码中仅调用了functionC。 getValues 方法从片段的主线程调用,但函数 A 和 FunctionB 被跳过

class MyViewModel() {
fun getValues(){
_livedata.value = SomeFuctionA()
_livedata.value = SomeFuctionB()
_livedata.value = SomeFuctionC()
}
}

但是,如果我修改方法以从主线程显式启动,则所有函数都会被调用

class MyViewModel() {
fun getValues(){
viewmodelScope.launch(Dispathers.Main){
_livedata.value = SomeFuctionA()
_livedata.value = SomeFuctionB()
_livedata.value = SomeFuctionC()
}
}
}

这是没有意义的,因为在这两种情况下 getValues 都是从 MainThread 调用的,但是仅在第二种情况下才能观察到所有函数。如何理想地确保所有三个功能都观察到实时数据?

android kotlin android-livedata android-viewmodel mutablelivedata
1个回答
0
投票

让我们讨论一下您的第一个代码片段,其中三个函数值保存在 _livedata 中,这里发生的情况是函数 A 的数据被函数 B 覆盖,然后被函数 C 覆盖。而且它发生得太快了,以至于你会发现函数 A 和函数 B 被跳过,因为函数 C 正在非常快地覆盖数据。

现在,讨论您的第二个代码片段,这里您使用了协程,并且由于该协程正在创建并延迟了函数、函数 B 和函数 C 的结果。因此,您可以获得结果,但它仍然是错误的,因为它最终会覆盖数据。 在这种情况下,您的代码也没有维护正确的编码标准。 u2028

所以,你的两个代码片段都是错误的(因为->设置值“_livedata.value =”将用新数据替换旧数据,这是liveData的一个功能)。

解决方案

您有多种方法可以解决这个问题。u2028u2028

  1. 使用列表将所有结果一起发出。u2028 您可以修改 liveData 以发出结果列表(来自所有函数),而不仅仅是单个结果(来自仅一个函数)。

这样观察者将收到一个包含函数A、函数B、函数C的所有数据的列表。

class MyViewModel : ViewModel() {
private val _livedata = MutableLiveData<List<ResultType>>() // Assume ResultType is the type returned by your functions
val livedata: LiveData<List<ResultType>> = _livedata

fun getValues() {
    // Collect all the results
    val results = listOf(
        SomeFunctionA(),
        SomeFunctionB(),
        SomeFunctionC()
    )

    // Emit the entire list
    _livedata.value = results
}

}

片段观察

viewModel.livedata.observe(viewLifecycleOwner, Observer { results ->
results.forEach { result ->
    // Process each result individually
}

})

  1. 使用MediatorLiveData。

如果您在知道数据何时来自之前使用过此功能 多个源,那么最好使用 mediatorLiveData,因为它添加了所有源 来自不同来源的数据并为您提供结果。



If you have not tried mediatorLiveData below is the official page of
it.

中介者LiveData

首先为每个函数创建不同的liveData,这将允许您单独处理liveData。

工作方式:

class MyViewModel : ViewModel() {
private val _liveDataA = MutableLiveData<ResultType>()
private val _liveDataB = MutableLiveData<ResultType>()
private val _liveDataC = MutableLiveData<ResultType>()

// Use MediatorLiveData to combine all LiveData results
val combinedLiveData = MediatorLiveData<List<ResultType>>().apply {
    val resultList = mutableListOf<ResultType>()

    // Add sources for each LiveData
    addSource(_liveDataA) { resultA ->
        resultList.add(resultA)
        value = resultList.toList()  // Update the MediatorLiveData with the combined result
    }

    addSource(_liveDataB) { resultB ->
        resultList.add(resultB)
        value = resultList.toList()
    }

    addSource(_liveDataC) { resultC ->
        resultList.add(resultC)
        value = resultList.toList()
    }
}

// Function to get values and update individual LiveData objects
fun getValues() {
    _liveDataA.value = SomeFunctionA()
    _liveDataB.value = SomeFunctionB()
    _liveDataC.value = SomeFunctionC()
}

}

MediatorLiveData 观察所有三个不同的 liveData 源(_liveDataA、_liveDataB、_liveDataC),并且每次任何函数(A、B、C)更新其各自的 liveData 时,mediatorLiveData 都会将结果合并到一个列表中并将其更新给观察者。

© www.soinside.com 2019 - 2024. All rights reserved.