Paging 3如何实现有网时优先请求API、无网时仅使用缓存数据
实现方案
- 先实现网络状态检测工具,可实时判断当前设备是否有可用网络连接,作为加载策略的判断依据
- 重写
RemoteMediator的load方法,调整加载触发逻辑:- 当加载类型为
LoadType.REFRESH(对应首次加载、下拉刷新、用户发起新搜索等场景)时,优先判断网络状态:- 有网络时直接发起API请求拉取最新数据,请求成功后按主键维度覆盖写入Room,不需要清空全量缓存
- 无网络时直接返回
MediatorResult.Success(endOfPaginationReached = true),终止远程加载流程,Paging会自动读取本地已有缓存展示
- 当加载类型为
LoadType.APPEND(滑动到列表底部加载下一页)时,保留原有逻辑即可:有网络时拉取下一页写入缓存,无网络时终止加载
- 当加载类型为
- 调整Pager初始化和调用逻辑:
- 不需要执行清空缓存的操作,每次需要拉取最新数据时,主动调用
pagingAdapter.refresh()触发LoadType.REFRESH流程即可 - 若需要每次进入页面自动拉取最新数据,可在Pager的流上追加
onStart事件触发刷新,示例代码如下:Pager( config = PagingConfig(pageSize = 20, enablePlaceholders = false), remoteMediator = YourCustomRemoteMediator(), pagingSourceFactory = { yourDao.queryPagingSource() } ).flow .onStart { // 每次订阅流时自动触发刷新,走自定义的REFRESH逻辑 emit(LoadState.Refresh) } .cachedIn(viewModelScope)
- 不需要执行清空缓存的操作,每次需要拉取最新数据时,主动调用
- Dao层的插入方法设置冲突策略为
OnConflictStrategy.REPLACE,新拉取的同主键数据会直接覆盖旧数据,不会产生重复条目,也不会影响其他未被覆盖的、关联了外键的缓存数据。
可选优化
- 如果是搜索场景,建议给缓存实体类新增
searchKeyword字段,拉取数据时写入当前搜索关键词,查询PagingSource时也按关键词过滤,不同搜索条件的缓存不会互相干扰,也不会误删其他场景下关联了外键的数据 - 若需要清理过期缓存,可给实体新增
updateTime字段,定期清理超过有效期且无外键关联的数据即可,不需要全量清空。
内容的提问来源于stack exchange,提问作者Ofek
相关产品推荐
相关产品推荐

