由于您有“刷新”场景并使用 Room db,我猜您正在使用 Paging3 和网络+本地 db 模式(使用 Room db 作为本地缓存)。
我在网络 + 本地数据库模式下也遇到过类似的情况。我不确定我是否正确理解了您的问题,或者您的情况与我的情况相同,但我还是会分享我所做的。
我使用的是什么:
- 分页3:3.0.0-beta01
- 房间:2.3.0-beta02
我所做的是让 Room 库创建 PagingSource(使用 Int 的键),并让 RemoteMediator 处理所有其他情况,例如在刷新和/或追加时从网络获取数据,以及插入获取成功后它们立即进入数据库。
我的dao 函数用于从房间库创建 PagingSource:
@Query("SELECT * FROM article WHERE isUnread = 1")
fun getUnreadPagingSource(): PagingSource<Int, LocalArticle>
在我的例子中,我将 Repository 类定义为在其构造函数中包含 dao 类,以便在创建 Pager 类时从存储库中调用上述函数。
我的自定义 RemoteMediator 类如下所示:
- 注意:在我的例子中,没有 PREPEND 情况,所以当参数
loadType 的值为 LoadType.PREPEND 时,RemoteMediator#load 函数总是返回 true。
class FeedMediator(
private val repository: FeedRepository
) : RemoteMediator<Int, LocalArticle>() {
...
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, LocalArticle>
): MediatorResult = runCatching {
when (loadType) {
LoadType.PREPEND -> true
LoadType.REFRESH -> {
feedRepository.refresh()
false
}
LoadType.APPEND -> {
val continuation = feedRepository.continuation()
if (continuation.isNullOrEmpty()) {
true
} else {
loadFeedAndCheckContinuation(continuation)
}
}
}
}.fold(
onSuccess = { endOfPaginationReached -> MediatorResult.Success(endOfPaginationReached) },
onFailure = {
Timber.e(it)
MediatorResult.Error(it)
}
)
private suspend fun loadFeedAndCheckContinuation(continuation: String?): Boolean {
val feed = feedRepository.load(continuation)
feedRepository.insert(feed)
return feed.continuation.isNullOrEmpty()
}
终于可以创建Pager类了。
fun createFeedPager(
mediator: FeedMediator<Int, LocalArticle>,
repository: FeedRepository
) = Pager(
config = PagingConfig(
pageSize = FETCH_FEED_COUNT,
enablePlaceholders = false,
prefetchDistance = PREFETCH_DISTANCE
),
remoteMediator = mediator,
pagingSourceFactory = { repository.getUnreadPagingSource() }
)
我希望它在某种程度上有所帮助..
其他参考资料:
编辑:
再次阅读文档后,我发现the doc明确指出:
RemoteMediator 用于将数据从网络加载到本地数据库。