【问题标题】:Do I have to use LiveData to read Query from Room DataBase in Android - Kotlin我是否必须使用 LiveData 从 Android 中的房间数据库中读取查询 - Kotlin
【发布时间】:2020-05-07 23:58:39
【问题描述】:

我使用 MVVM 模型开发了一个简单的购物清单 App。

我有这些文件:

  • Database(2 表:购物项目和参考项目)+DAO(唯一)
  • Repository(唯一)
  • ViewModel(唯一)
  • Fragment/Activity

DAO 中,我定义了所有查询。目前,我所有的//Custom 查询都返回一个LiveData<> 类型,如下所示:

@Dao
interface ShoppingDao {

    // Shopping Items
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertShoppingItem(item: ShoppingItem)

    @Delete
    suspend fun deleteShoppingItem(item: ShoppingItem)

    @Update
    suspend fun updateShoppingItem(item: ShoppingItem)

    @Query(value = "DELETE FROM shopping_items")
    suspend fun deleteAllShoppingItems()

    @Query(value = "SELECT * FROM shopping_items")
    fun getAllShoppingItem(): LiveData<List<ShoppingItem>>

    // Custom
    @Query(value = "SELECT COALESCE(SUM(item_amount),0) FROM shopping_items")
    fun getAllShoppingCount(): LiveData<Int>

    @Query(value = "SELECT COALESCE(SUM(item_total_price), 0.0) FROM shopping_items")
    fun getAllShoppingTotal(): LiveData<Float>

然后在存储库中,它们都没有使用suspend fun 来调用。因此,在 ViewModel 中,它们也不会使用 suspend fun 来调用。

我想使用getAllShoppingCount(),例如不使用LiveDataObserver

有可能吗?

这是最佳实践吗?

如果没有 LiveData,我将不得不使用 suspend fun 来完成我的 Query,但是当我使用时:

fun updateShoppingItem(item: ShoppingItem) = CoroutineScope(Dispatchers.Main).launch {
    repository.updateShoppingItem(item)
}

它返回 Job 而不是 Query 应该返回的类型。如果我可以使用 LiveData 以外的其他内容,我该如何更改。

【问题讨论】:

  • 它应该可以帮助你:stackoverflow.com/questions/55484682/…
  • 谢谢,但不依赖对所有问题的回答。我之前读过,但它只是说 Dao 不应该在那之后返回 LiveData ?
  • 主线程无法访问数据库,所以首先需要使用Dispatcher.IO,然后在dao函数之前使用suspend,并为其设置返回类型

标签: android android-room android-mvvm


【解决方案1】:

我的想法:

  1. 没有“您必须在房间内使用 LiveData”的限制。有“你可以使用 LiveData”(link to documentation)。您还可以使用其他实现模式观察者的技术 - RxJavaCoroutines Flow。您可以使用这些机制来实现数据中的反应式流动 - 本地数据库中的某些变化,您的 Fragment/Activity 将立即观察到该变化。
  2. 没有“您不应该在房间中使用 LiveData”的限制。在提到的文章中,它只是一个答案——“如果你不想使用 LiveData——那么你不应该使用它”。可能有一些趋势是用 Coroutines Flow 代替 Kotlin 中的 LiveData,但现在要求不高。
  3. 您可以使用异步Coroutines as well。在这种情况下,您将不会观察到数据库中的变化。在您的 viewModel 中,您可以在 KTX extension 的帮助下更轻松地调用挂起函数

    viewModelScope.launch(Dispatchers.IO) { repository.updateShoppingItem(item) }

  4. 但究竟有什么用,“你可以用这个”和“你可以用那个”太多了?好吧,像往常一样 - 这取决于,并且没有单一的最佳方法,并且有很多“如果”。如果您不需要在线观察数据的变化并且您使用 Kotlin 并且您熟悉协程 - 您可以使用它们。如果您在这种情况下使用 Java 并且您不熟悉 RxJava 并且您不想研究它(为什么?)您必须费心地将所有使用 db 的代码手动移动到另一个线程中。如果您是 RxJava 爱好者 - 即使您使用 Kotlin,也可以使用它。如果您是 RxJava 爱好者,但又想走在潮流的前沿 - 您可以使用 Flow。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-21
    • 2020-05-01
    • 2022-01-24
    • 1970-01-01
    • 2020-02-06
    • 2018-08-27
    • 1970-01-01
    相关资源
    最近更新 更多