android - 与 Room 和 SharedPreferences 交互时的最佳实践
问题描述
我正在使用一个带有“收藏夹”字段的Room
表格,该字段默认为,但可以通过. 需要定期擦除并由. 这样做自然会将所有“收藏”字段恢复为.entity
boolean
False
True
user input
database
network call
False
使用SharedPreferences
,我可以保留第二个持久的 Favorited 列表entities
,但是重新填充Room
并保留收藏夹的最干净的方法是什么?
在这里使用RxKotlin
是为了清楚起见,如果不是准确的话,应该是这样的
saveEntities()
.flatMapIterable { it }
.map{
if (sharedPrefs.contains(it.id))
it.apply{favorite}
else it }
.toList()
.subscribe()
或者我应该serialize
列出收藏夹,将其保存到SharedPreferences
,然后
val favoritesList = PrefSerializer().getFavorites
saveEntities()
.map{ it.forEach{
if (favoritesList.contains(it))
it.apply{favorite}
else it}
}
.subscribe()
或者将收藏信息存储在其中是否有意义Room
?SharedPreferences
每次调用实体时都引用感觉像是不好的做法。
解决方案
我建议在 Room 中使用 2 个表,因为这样您可以使用数据库视图来组合它们。Room 可以监控表格并通过 LiveData 通知 UI。您可以在技术上监控 SharedPreferences,但我相信它实际上更乏味。
例如,这是一个数据被同步定期覆盖的表。
@Entity
data class Cheese(
@PrimaryKey
val id: Long,
val name: String
)
你有一个单独的表来保存“最喜欢”的状态。
@Entity
data class CheeseFavorite(
@PrimaryKey
val id: Long,
val favorite: Boolean
)
然后你可以创建一个这样的数据库视图来组合 2 个表。
@DatabaseView(
"""
SELECT c.id, c.name, f.favorite
FROM Cheese AS c
LEFT OUTER JOIN CheeseFavorite AS f
ON c.id = f.id
"""
)
data class CheeseDetail(
val id: Long,
val name: String,
val favorite: Boolean?
)
可以像查询表格一样查询视图。您当然可以使用 LiveData 或 Rx 数据类型作为返回类型。
@Query("SELECT * FROM CheeseDetail")
fun all(): List<CheeseDetail>
推荐阅读
- c# - 用于捕获其他字符不跟随的数字模式的正则表达式
- hyperledger-fabric - 我想构建一个 Hyperledger Fabric 网络,在多个组织的多个主机上运行
- java - 如何将临时授予的 ContentProvider 权限传递给 Service?
- c# - 登录网站并使用 Html Agility Pack 设置用户代理
- swift - 如何使用枚举创建计算函数?
- docker - Dockerfile 的第一行 - 什么操作系统?
- authorization - 为动态角色和属性建模 XACML 策略
- kubernetes - Traefik 入口不适用于集群 IP
- ionic-framework - 如何将我的 Ionic 4 应用程序升级到最新的 Ionic 版本?
- css - 如何使用来自其父级的 ::after 的通用兄弟选择器