android - 我是否必须使用 LiveData 从 Android 中的房间数据库中读取查询 - Kotlin
问题描述
我使用 MVVM 模型开发了一个简单的购物清单应用程序。
我有这些文件:
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 中,它们也不使用 asuspend fun
来调用。
例如,我想使用getAllShoppingCount()
不使用 aLiveData
和Observer
.
可能吗 ?
这是最佳做法吗?
如果没有 LiveData,我将不得不使用suspend fun
我的Query
,但是当我使用时:
fun updateShoppingItem(item: ShoppingItem) = CoroutineScope(Dispatchers.Main).launch {
repository.updateShoppingItem(item)
}
它返回的Job
不是Query
应该返回的类型。如果我可以使用除LiveData
.
解决方案
我的想法:
- 没有限制“您必须在房间中使用 LiveData”。有“您可以使用 LiveData”(文档链接)。您还可以使用另一种技术实现模式 Observer- RxJava,Coroutines Flow。您可以使用这些机制中的一种来实现数据中的反应性流 - 本地数据库中的某些变化,您的片段/活动将立即观察到该变化。
- 没有限制“你不应该在房间里使用 LiveData”。在提到的文章中,它只是一个答案——“如果你不想使用 LiveData——那么你不应该使用它”。可能有一些趋势是用 Coroutines Flow 代替 Kotlin 中的 LiveData,但现在要求不高。
您也可以使用异步协程。在这种情况下,您将不会观察到数据库中的变化。在您的 viewModel 中,借助KTX 扩展,您可以更轻松地调用挂起功能
viewModelScope.launch(Dispatchers.IO) { repository.updateShoppingItem(item) }
但究竟有什么用,“你可以用这个”和“你可以用那个”太多了?好吧,像往常一样 - 这取决于,并且没有单一的最佳方法,并且有很多“如果”。如果您不需要在线观察数据的变化并且您使用 Kotlin 并且您熟悉协程 - 您可以使用它们。如果您在这种情况下使用 Java 并且您不熟悉 RxJava 并且您不想研究它(为什么?)您必须费心地将所有使用 db 的代码手动移动到另一个线程中。如果您是 RxJava 爱好者 - 即使您使用 Kotlin,也可以使用它。如果您是 RxJava 粉丝,但又想站在趋势的边缘 - 您可以使用 Flow。
希望这会有所帮助。
推荐阅读
- angular - 插值不适用于点击方法
- image - 如何通过 http post 上传 QPixmap 图像?
- vb.net - VB.net Crystal 报表导出为 html 并使用 Outlook 作为 html 邮件正文发送
- sql - 如何根据月份参数值将数据从一年的开始月份拉到给定月份
- swift - 如何将 AttributedString 转换为 NSMutableString Swift?
- java - 当 jar 位于 zip 文件中时,如何过滤 jar 中的特定文件夹?
- javascript - 我可以将 jQuery UI 分类在文档上吗?
- python - 如何处理 HTTP 服务器中的多个请求?
- python - ImportError:没有名为 json 的模块
- angular - 如何在 matDatepicker 中为表单控件转换纪元格式