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
相关产品推荐
相关产品推荐

