如何正确组合两个实时数据对象
Posted
技术标签:
【中文标题】如何正确组合两个实时数据对象【英文标题】:How to make a combination of two live data objects properly 【发布时间】:2021-02-10 10:22:54 【问题描述】:我有两个相同类型的 LiveData 对象,我想对输出进行相同的计算。像 Rx 中的合并运算符之类的东西我怎么能做到这一点。目前我正在这样做:
class VM : ViewModel()
val input1LiveData = MutableLiveData<Int>()
val input2LiveData = MutableLiveData<Int>()
val squareLiveData = MutableLiveData<Int>()
class MyFragment : Fragment()
private void fillSquare(input: Int)
viewmodel.squareLiveData.value = input * input
override onViewCreated()
viewmodel.input1LiveData.observe(viewLifecycleOwner)
fillSquare(it * it)
viewmodel.input2LiveData.observe(viewLifecycleOwner)
fillSquare(it * it)
我猜这是一个不好的方法
【问题讨论】:
【参考方案1】:您可以使用MediatorLiveData
,它是一种特殊类型的 LiveData,能够连接到其他 liveData 对象作为源。您可以像这样改进上面的代码:
class VM : ViewModel()
val input1LiveData = MutableLiveData<Int>()
val input2LiveData = MutableLiveData<Int>()
val squareLiveData = MediatorLiveData<Int>().apply
val observer = Observer<T> value = it*it
addSource(input1LiveData, observer)
addSource(input2LiveData, observer)
class MyFragment : Fragment()
override onViewCreated()
viewmodel.squareLiveData.observe(viewLifecycleOwner)
//do your ui updates
上面的代码将创建一个有 2 个源的 MediatorLiveData
对象,观察者将计算平方并设置值。
您也可以使用ReactiveLiveData 库,通过反应式方法来实现这一点,使代码更易于编写和阅读:D 就像这样。
class VM : ViewModel()
val input1LiveData = MutableLiveData<Int>()
val input2LiveData = MutableLiveData<Int>()
val squareLiveData = input1LiveData.merge(input2LiveData).mapit*it
class MyFragment : Fragment()
override onViewCreated()
viewmodel.squareLiveData.observe(viewLifecycleOwner)
//do your ui updates
【讨论】:
【参考方案2】:提供的答案是正确的,确实是可以解决这个问题的MediatorLiveData,例如:
public class CombinedLiveData2<A, B> extends MediatorLiveData<Pair<A, B>>
private A a;
private B b;
public CombinedLiveData2(LiveData<A> ld1, LiveData<B> ld2)
setValue(Pair.create(a, b));
addSource(ld1, (a) ->
if(a != null)
this.a = a;
setValue(Pair.create(a, b));
);
addSource(ld2, (b) ->
if(b != null)
this.b = b;
setValue(Pair.create(a, b));
);
如果您想为更多 LiveData 执行此操作,可以使用 https://github.com/Zhuinden/livedata-combinetuple-kt/
class VM : ViewModel()
val input1LiveData = MutableLiveData<Int>(0)
val input2LiveData = MutableLiveData<Int>(0)
val squareLiveData = combineTupleNonNull(input1LiveData, input2LiveData)
.map (input1, input2) ->
/* do transform */
class MyFragment : Fragment()
override onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
viewmodel.squareLiveData.observe(viewLifecycleOwner)
// do something with square value
【讨论】:
以上是关于如何正确组合两个实时数据对象的主要内容,如果未能解决你的问题,请参考以下文章
大数据架构:flume-ng+Kafka+Storm+HDFS 实时系统组合
iOS 内存占用的正确统计数据是啥。实时字节?真实记忆?其他?