为什么带有Mediator的paging3会无限加载APPEND

问题描述 投票:0回答:2

当我通过paging3将数据加载到recyclerview时,数据将被无限加载......(这意味着我的APPEND将不断执行,并且会不断访问我的网络服务来加载数据)

这是关键代码

Dao is used to operate the StoriesBean

ConstantDao is to operate the latest
日期
that has been stored.

@Dao
interface ConstantDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(bean:ConstantKey)

    @Query("DELETE FROM constant_key")
    suspend fun clear()

    @Query("DELETE FROM constant_key WHERE key = :key")
    suspend fun delete(key: String)

    @Query("SELECT * FROM constant_key WHERE key = :key")
    fun get(key:String):ConstantKey

}
@Dao
interface Dao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(passwords: List<StoriesBean>)

    @Query("DELETE FROM mydata")
    suspend fun clear()

    @Query("SELECT * FROM mydata")
    fun getAll(): PagingSource<Int, StoriesBean>
}

    private val dao: Dao = db.dao()
    private val keyDao: ConstantDao = db.constantDao()


    lateinit var date:String
    lateinit var list:List<StoriesBean>


override suspend fun load(
        loadType: LoadType,
        state: PagingState<Int, StoriesBean>
    ): MediatorResult {
        try {


            date = when (loadType) {
                LoadType.REFRESH -> {
                    Util.getTodayDate()
                }
                LoadType.PREPEND -> {
                    return MediatorResult.Success(endOfPaginationReached = true)
                }
                LoadType.APPEND -> {
                    val constantKey = db.withTransaction {
                        keyDao.get(KEY_MY)
                    }


                    if (constantKey.value.isEmpty()) {
                        return MediatorResult.Success(endOfPaginationReached = true)
                    }
                    constantKey.value
                }
            }



            list =
                if (loadType == LoadType.REFRESH) {
                    val a =service.getLatestNews().stories
                    a
                } else {

                    date = DateUtil.getPreviousString(date)


                    val b = service.getBeforeNews(date).stories


                    b

                }

            db.withTransaction {
                if (loadType == LoadType.REFRESH) {
                    dao.clear()
                    keyDao.delete(KEY_MY)
                }

                dao.insert(list)
                keyDao.insert(ConstantKey(KEY_MY, date))
            }
            return MediatorResult.Success(endOfPaginationReached = list.isEmpty())
        } catch (e: Exception) {
            if (loadType == LoadType.APPEND)
                date = DateUtil.getNextString(date)
            return MediatorResult.Error(Throwable(message = "error"))
        }
    }

我有另一个地方可以使用Mediator,但是它可以工作。但是现在,我想再次使用Mediator,它有这个问题:我的数据加载无限APPEND....

我曾经猜测可能是Recyclerview的高度,但我把它从wrap_content改为match_parent,它也无限加载...

我也没有将 NestScrollView 添加为 Recyclerview 的父视图组。

android kotlin android-jetpack android-paging
2个回答
0
投票

创建PageConfig对象时验证pageSize值。也许现在还太小了

根据文档:

应该是屏幕上可见项目数量的几倍。 配置页面大小取决于数据的加载和使用方式。较小的页面大小可以改善内存使用率、延迟并避免 GC 流失。较大的页面通常会在一定程度上提高加载吞吐量(避免一次从 SQLite 加载超过 2MB,因为这会产生额外的成本)。 如果您正在加载占据大部分屏幕的大型社交媒体风格卡片的数据,并且您的数据库不是瓶颈,则 10-20 可能是有意义的。如果您在平铺网格中显示数十个项目,这可以在滚动过程中更快地显示项目,请考虑接近 100 个。


0
投票

我猜您要么在 UI 中对数据进行了错误的排序和/或使用了错误的密钥来获取下一页。我遇到了类似的问题,我按创建日期对数据进行排序,但我使用的 API 没有根据创建日期返回数据;而是通过项目 ID。虽然它们通常是按时间顺序排列的,但并不十分准确。 API 调用响应中间会有一个随机项,该项的创建速度比其他项要早。这导致我的远程中介始终使用列表中心的项目 ID 进行追加,而不是末尾的项目。然后,当我使用该 ID 时,下一页将具有与原始刷新调用中相同的项目。

我建议您仔细查看返回的网络响应,看看刷新调用和追加调用是否包含相同的项目。

© www.soinside.com 2019 - 2024. All rights reserved.