You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MVP架构下使用Paging3与RxJava遇数据加载异常问题

问题根源与解决方案

核心问题

你代码里使用了RxJava的subscribe方法,这是异步非阻塞的调用——调用后代码会立刻继续执行responseData.addAll(data),但此时网络请求还在后台处理,data还没被赋值(甚至会因为lateinit未初始化触发异常)。而你看到的日志是网络请求完成后才打印的,这就造成了「日志有数据但RecyclerView为空」的矛盾。

修复方案

在PagingSource的suspend函数中,必须等待RxJava异步任务完成后再返回结果。可以通过RxJava与协程的适配扩展来实现,步骤如下:

  1. 先确保引入协程-RxJava适配依赖(以Rx3为例):
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx3:1.7.3"
  1. 修改RepoPagingSource代码:
class RepoPagingSource @Inject constructor(
    private val repository: ApiRepository,
    val context: Context
) : PagingSource<Int, RepositoryResponse>() {

    private lateinit var sharedPref: SharedPref

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, RepositoryResponse> {
        sharedPref = SharedPref(context)
        return try {
            val currentPage = params.key ?: 1
            // 用await()让协程等待RxJava请求完成,同步获取响应
            val response = repository
                .getRepositories("bearer ${sharedPref.accessToken}", currentPage)
                .applyIoScheduler()
                .await()

            val responseCode = response.code().toString()
            // 处理body为空的情况,避免空指针
            val data = response.body() ?: mutableListOf()

            Log.d("RepoPagingSource", responseCode)
            Log.d("RepoPagingSource", data.size.toString())
            Log.d("RepoPagingSource", data.toString())

            LoadResult.Page(
                data = data,
                // 修正prevKey:上一页应为currentPage-1,而非固定-1
                prevKey = if (currentPage == 1) null else currentPage - 1,
                // 当返回数据为空时,停止加载下一页
                nextKey = if (data.isEmpty()) null else currentPage + 1
            )
        } catch (e: Exception) {
            LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, RepositoryResponse>): Int? {
        // 优化refreshKey逻辑,让Paging在刷新时能定位到当前页面附近
        return state.anchorPosition?.let { anchorPosition ->
            state.closestPageToPosition(anchorPosition)?.prevKey ?: state.closestPageToPosition(anchorPosition)?.nextKey
        }
    }
}

额外修正说明

  • 移除了不必要的lateinit变量,避免未初始化的风险;
  • 修正了prevKey的错误逻辑(之前固定为-1会导致Paging无法正确加载上一页);
  • 添加了nextKey的空数据判断,避免无效的下一页请求;
  • 处理了response.body()为空的场景,防止空指针异常。

内容的提问来源于stack exchange,提问作者Rey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:37:34