使用Paging 3与Retrofit时,空响应引发PagingSource无限循环的解决方法
解决Paging3遇空列表无限循环的问题
问题根源
你的代码里有几个关键问题导致了无限循环:
- 用全局
responseData手动累加数据,即使当前页为空,Paging也会因为拿到非空列表(之前累加的数据)继续请求下一页 - 不管接口返回数据是否为空,都固定把
nextKey设为currentPage+1,Paging会不断发起下一页请求 - Retrofit响应处理逻辑混乱,错误分支没有正确返回
LoadResult,还存在语法错误(LoadResult.Page的括号位置错了)
修复方案
- 移除全局的
responseData,Paging3会自动处理多页数据的拼接,不需要手动维护 - 根据当前页返回的数据是否为空,动态设置
nextKey:空数据时设为null,告诉Paging没有更多内容了 - 规范Retrofit的响应错误处理,确保请求失败时正确返回错误结果
- 修正
LoadResult.Page的参数格式错误
修正后的完整代码
class DataAPIPagingSource(private val token: String, private val apiCalls: APICalls) : PagingSource<Int, DataAPI>() { override fun getRefreshKey(state: PagingState<Int, DataAPI>): Int? { return null } override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DataAPI> { return try { val currentPage = params.key ?: 1 val response = apiCalls.getData(token) // 先校验接口请求是否成功 if (!response.isSuccessful) { return LoadResult.Error(Exception("请求失败:${response.code()} ${response.message()}")) } val data = response.body()?.listData ?: emptyList() // 只有当前页有数据时,才生成下一页的key val nextKey = if (data.isNotEmpty()) currentPage + 1 else null // 上一页key:第一页设为null,否则是当前页减一 val prevKey = if (currentPage == 1) null else currentPage - 1 // 返回当前页的数据,Paging会自动拼接所有页内容 LoadResult.Page( data = data, prevKey = prevKey, nextKey = nextKey ) } catch (e: Exception) { LoadResult.Error(e) } } }
关键说明
- 不再手动维护数据列表:Paging3的
LoadResult.Page只需要传入当前页的数据,Paging库内部会自动把多页数据合并展示 - 动态控制分页开关:当接口返回空列表时,
nextKey设为null,Paging就会停止加载更多,避免无限循环 - 规范错误处理:确保接口请求失败(比如HTTP状态码非200)时,正确返回
LoadResult.Error,让UI可以处理错误状态
内容的提问来源于stack exchange,提问作者HeraGonz
相关产品推荐
相关产品推荐

