【问题标题】:kotlin coroutine distinctUntilChanged work incorrect with roomkotlin 协程 distinctUntilChanged 与房间工作不正确
【发布时间】:2021-12-17 12:59:19
【问题描述】:

我的 android 本地数据库中有表 Stories。 问题: 当我设置story.isSeen = true 并将其保存到本地数据库时,我在distinctUntilChanged { old, new -> } 中获得了可观察的数据,但oldnew 的值总是相同的。 old[n].isSeen 是真的,虽然它是假的。
distinctUntilChanged() 也没有工作。
故事结构:

@Keep
@Entity(tableName = "stories")
@Parcelize
data class Story (
    @PrimaryKey
    var id: Int,
    var name: String,
    var iconName: String,
    var isAttached: Boolean = false,
    var lastShownPosition: Int,
    var isSeen: Boolean = false,

    @TypeConverters(DateConverter::class)
    var expiresAt: Date,

    @TypeConverters(DateConverter::class)
    var createdAt: Date,

    @TypeConverters(StoryItemsConverter::class)
    var items: List<StoryItem>
): Parcelable

我用Flow来观察数据:

    @Query("SELECT * FROM stories WHERE :today <= expiresAt LIMIT :limit OFFSET :offset ")
    fun getStories(today: Long, limit: Int = -1, offset: Int = 0): Flow<MutableList<Story>>

以及我如何观察它们:

    suspend fun getStories(sync: Boolean = false, params: JSONObject = defaultStoriesQueryParams) {
        val today = System.currentTimeMillis()

        storiesDao.getStories(today).distinctUntilChanged { old, new ->
            if (new.size != old.size) return@distinctUntilChanged false
            for (i in 0..new.size) {
                if (old[i].isSeen != new[i].isSeen) return@distinctUntilChanged false
            }
            return@distinctUntilChanged true
        }.collect { newData ->

            if (newData.isNullOrEmpty()) {
                _storiesFlow.emit(StoriesResource.Loading())

                val remoteData = syncStories(params)
                when {
                    remoteData == null -> _storiesFlow.emit(StoriesResource.Error("Request error"))
                    remoteData.code != 200 -> _storiesFlow.emit(StoriesResource.Error(remoteData.message))
                    remoteData.code == 200 && remoteData.payload.isNullOrEmpty() -> _storiesFlow.emit(StoriesResource.Empty())
                }
            } else {
                _storiesFlow.emit(StoriesResource.Data(newData))
            }
        }
    }

我如何保存更改:

fun update(story: Story) {
        GlobalScope.launch(Dispatchers.IO) {
            storiesDao.updateStories(story)
        }
    }

附:对不起我的英语,如果做错了。

【问题讨论】:

    标签: android android-room coroutine flow


    【解决方案1】:

    问题解决了。房间在缓存中保存最后一个请求对象引用。此参考还用于查看更改对象的位置。这就是为什么我将更改的对象与更改的对象进行比较。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    • 谢谢@ouflak
    猜你喜欢
    • 2019-06-28
    • 2020-01-04
    • 2020-04-08
    • 1970-01-01
    • 2019-08-19
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多