在Android中向ViewModel传递单个对象时,是否应使用Kotlin流?

mm9b1k5b  于 2023-01-15  发布在  Android
关注(0)|答案(2)|浏览(174)

在不同的场合,我看到人们在从本地数据库检索对象列表时使用Kotlin,但是在检索单个对象(而不是列表)时,我没有注意到任何关于使用它们的警告/错误,甚至没有注意到Flows只能在列表上使用的规范
我的问题是,在单个对象上使用流会导致错误/问题吗?如果不会,它会影响性能吗?如果不会,那么为什么它通常不被使用呢?
我的意思的示例代码:

  • 使用流检索单个对象:
@Query("SELECT * FROM objects WHERE id = :id")
fun getObjectById(id: Int): Flow<Object>
  • 正在ViewModel中检索函数:
fun objectRetrieval(id: Int) {

    // ... More code

    getObjectById(id)
        .onEach { object: Object ->
            // Operations
        }
        .launchIn(viewModelScope)
}

感谢您抽出宝贵时间!

kgqe7b3p

kgqe7b3p1#

我认为这里有多个误解,无论是在问题中还是在评论/回答中。
流实际上与异步处理的值序列有关,简单地说就是:如果将来我们计划多次接收某个数据,流就是为了这个目的。例如:用户事件、即时消息应用中的传入消息等。
如果我们计划只接收一次数据,我们仍然可以使用flow,但这是一种过度的做法,并且会增加不必要的复杂性。在这种情况下,最好使用suspend函数,因为它更容易使用,而且很清楚数据只接收一次。
然而,我们接收到的数据是单个对象还是对象列表并不重要,事实上,列表也是一个对象:

  • suspend fun foo(): String-接收单个对象一次。
  • suspend fun foo(): List<String>-一次接收一个对象列表。
  • fun foo(): Flow<String>-多次接收单个对象。
  • fun foo(): Flow<List<String>>-多次接收对象列表。

以上所有情况都是有意义的,并且可以用于不同的场景。
现在,回到你的具体例子,这里还有另一个误解。你的getObjectById()并不是只接收一个值,而是一个值序列。通过使用Flow,我们告诉Room我们想要观察数据的变化。首先,它发送给你对象的当前数据,但是如果对象发生变化,你会再次接收更新的数据。
如果您只想获取当前数据而不想观察变化,请改用suspend函数。

ki1q1bka

ki1q1bka2#

是的,你应该流动单一对象单一来源的真相架构

val numLightsObserver: Observer<Int> = Observer { i: Int ->
        i.let { jx.setTitle(i.toString()) }
    }
    wordViewModel.numLights.observe(this, numLightsObserver)

现在我有了一个完全自动化的UI对象,我将如何处理灯的数量。上面我将它转换为一个字符串用于此演示提交。
这是一个提交diff链接,我不得不修改4个文件以使它在github上运行diff,我尝试让它流过一个对象

相关问题