在 Android 中对 mutableList 使用 stateflow

Using stateflow for mutableList in Android

正在处理一个项目,我们需要在视图模型中有一个项目列表。类型为自定义数据class.

到现在为止,我一直使用MutableLiveData来存储列表的状态。当用户扫描我们已连接到设备的 RFID reader 上的项目时,该列表将被更新。扫描后,将从服务器获取一个项目,并相应地更新列表。

我想尝试继续使用 StateFlow,但我 运行 遇到了问题。

当扫描到新项目时,我将使用 add 命令更新可变列表,然后更新列表中的相应项目。这不会触发 LiveDataStateFlow observers/collectors - 但是使用 LiveData 我可以在完成更新后将列表分配给自己。 (_listOfItems.value = _listOfItems.value) 因为这会通知观察员。

然而,这不适用于 StateFlow,因为它仅在引用更改时触发(它不会触发,因为它是同一个列表,只是其中包含 new/changed 项)。

我知道使用可变列表和协程更新同一个列表可能存在一些问题,因为如果尝试同时更新列表或类似的事情,它可能会发生冲突。

所以,通常的问题是:当在视图模型中有一个列表并在列表内容更改时更新 UI 时最好的方法是什么?

不可能在 StateFlow 中使用 MutableList 并使其更新,因为 StateFlow 总是与先前的值进行相等比较,并且由于先前的值是同一列表的实例,因此它们将始终被考虑等于。

您可以使用 SharedFlow 完成这项工作,它不会与之前的值进行比较。

然而,将可变 类 与 SharedFlow/StateFlow(甚至 LiveData)一起使用通常很容易出错,因为数据可能会从多个不同的地方读取和写入。很难管理。

一个解决方案是每次将列表发送到流程时创建一份列表副本:

myMutableStateFlow.value = myMutableList.toList()

如果您想要更易于管理的代码(可能以牺牲性能为代价),则根本不要使用可变列表。使用 read-only 列表。你可以把它放在 var 属性 中,或者直接修改你的 StateFlow 的 value

myMutableStateFlow.value += someNewItems
// where myMutableStateFlow's type is a List, not MutableList