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

Paging Library cachedIn()函数调用失效:val与函数实现差异问询

Paging 3缓存失效问题:方法调用vs变量引用的差异分析与解决

问题现象

实现Paging 3分页功能时出现明显差异:

  • 使用pagedItems变量收集Flow:cachedIn()缓存功能正常,设备旋转后不会重新发起请求。
  • 调用pagedItems()方法收集Flow:cachedIn()缓存失效,设备旋转后会重新发起请求。

观察到设备旋转后,pagedItems()返回的Flow哈希值会变化,而pagedItems变量的哈希值保持不变。

ViewModel代码示例

// 正常工作:缓存生效
val pagedItems = useCase.invoke(PAGE_SIZE).cachedIn(viewModelScope)

// 缓存失效:每次调用生成新Flow
fun pagedItems(): Flow<PagingData<Result>> {
    return useCase.invoke(PAGE_SIZE).cachedIn(viewModelScope) 
}

Fragment代码示例

viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
    // 正常工作:复用同一个缓存的Flow
    launch {
        viewModel.pagedItems.collect { pagedData ->
            pagingAdapter.submitData(pagedData)
        }
    }
    // 重新发起请求:每次调用方法都得到新Flow
    launch {
        viewModel.pagedItems().collect { pagedData ->
            pagingAdapter.submitData(pagedData)
        }
    }
}

差异原因

  • 变量pagedItems:ViewModel初始化时仅创建一次Flow实例,cachedIn(viewModelScope)将分页数据缓存到ViewModel的作用域中。由于设备旋转时ViewModel不会重建,这个Flow实例始终存在,缓存数据也得以保留,哈希值自然不变。
  • 方法pagedItems():每次调用都会执行useCase.invoke(PAGE_SIZE).cachedIn(viewModelScope),生成全新的Flow实例。设备旋转后Fragment重新调用该方法时,得到的是未携带之前缓存的新Flow,因此会重新发起请求,哈希值每次都不同。

解决方案

使用val关键字定义变量,确保Flow实例唯一,让cachedIn()的缓存能在ViewModel作用域内持续生效:

// 正确实现:缓存稳定生效
val pagedItems = useCase.invoke(PAGE_SIZE).cachedIn(viewModelScope)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:25:17