简体   繁体   English

我是否必须使用 LiveData 从 Android - Kotlin 中的房间数据库中读取查询

[英]Do I have to use LiveData to read Query from Room DataBase in Android - Kotlin

I develop a simple grocery list App using MVVM model.我使用 MVVM model 开发了一个简单的购物清单应用程序。

I have those files:我有这些文件:

  • Database (2 Tables: Shopping Item and Reference Item) + DAO (unique) Database (2 表:购物项目和参考项目)+ DAO (唯一)
  • Repository (Unique) Repository (唯一)
  • ViewModel (Unique) ViewModel (唯一)
  • Fragment / Activity Fragment / Activity

In the DAO , I define all my queries.DAO中,我定义了所有查询。 Currently, all my //Custom queries return a LiveData<> type like this:目前,我所有的//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>

Then in the repository none of them use suspend fun to be called.然后在存储库中,他们都没有使用suspend fun来调用。 Thus, in the ViewModel they also don't use a suspend fun to be called.因此,在 ViewModel 中,它们也不会使用suspend fun来调用。

I would like to use getAllShoppingCount() for example without using a LiveData with an Observer .例如,我想使用getAllShoppingCount()而不使用LiveDataObserver

Is it possible?可能吗?

Is it a best practice?这是最佳实践吗?

Without the LiveData, I will have to use suspend fun to do my Query , but when I use:如果没有 LiveData,我将不得不使用suspend fun来执行我的Query ,但是当我使用时:

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

It returns a Job not the type the Query should return.它返回一个Job不是Query应该返回的类型。 How can I change that if I can use something else than LiveData .如果我可以使用LiveData以外的其他东西,我该如何改变它。

My thoughts:我的想法:

  1. There is no restriction "you have to use LiveData in Room".没有限制“您必须在房间中使用 LiveData”。 There is "you can use LiveData" ( link to documentation ).有“你可以使用 LiveData”( 链接到文档)。 As well as you can use another techniques implementing pattern Observer - RxJava , Coroutines Flow .您还可以使用另一种技术实现模式 Observer- RxJavaCoroutines Flow You can use on of these mechanism to achieve reactive flow in your data - something changes in local DB, your Fragment/Activity will observe that change instantly.可以使用这些机制中的一种来实现数据中的反应性流 - 本地数据库中的某些变化,您的片段/活动将立即观察到该变化。
  2. There is no restriction "you shouldn't use LiveData in Room".没有“你不应该在房间里使用 LiveData”的限制。 In mentioned article it was just an answer - "If you don't want use LiveData - well, then you shouldn't use it".在提到的文章中,它只是一个答案——“如果你不想使用 LiveData——那么你不应该使用它”。 May be, there is some trend to replace LiveData in Kotlin with Coroutines Flow, but it's not demanding now.可能有一些趋势是用 Coroutines Flow 代替 Kotlin 中的 LiveData,但现在要求不高。
  3. You can use asynchronous Coroutines as well .您也可以使用异步协程 In that case you'll not observe changes in your db.在这种情况下,您将不会观察到数据库中的变化。 In your viewModel you call your suspend-function easier with the help of KTX extension在您的 viewModel 中,借助KTX 扩展,您可以更轻松地调用挂起功能

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

  4. But what exactly use, there are too many "you can use this" and "you can use that"?但究竟有什么用,“你可以用这个”和“你可以用那个”太多了? Well, as usual - it depends, and there is no single best-method, and there are lot of "if".好吧,像往常一样 - 这取决于,并且没有单一的最佳方法,并且有很多“如果”。 If you don't need to observe changes in your data on-line and you use Kotlin and you're familiar with coroutines - you can use them.如果您不需要在线观察数据的变化并且您使用 Kotlin 并且您熟悉协程 - 您可以使用它们。 If you use Java in that case and you're not familiar with RxJava and you don't want to study it (still why?) you have to bother to manually move all your code working with db into another Thread.如果您在这种情况下使用 Java 并且您不熟悉 RxJava 并且不想研究它(仍然为什么?)您必须手动将所有使用 db 的代码移动到另一个线程中。 If you a RxJava fan - you can use it even if you use Kotlin.如果您是 RxJava 粉丝 - 即使您使用 Kotlin,您也可以使用它。 If you a RxJava fan but you want to be on the edge of trends - you can use Flow.如果您是 RxJava 粉丝,但又想站在趋势的边缘 - 您可以使用 Flow。

Hope this will help.希望这会有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM