8

我正在使用最新的 Jetpack 库。
Pagination3 版本:3.0.0-alpha05
房间版本:2.3.0-alpha02

我的实体有 Long asPrimaryKey和 Room 可以PagingSource为其他Int类型生成。

error: For now, Room only supports PagingSource with Key of type Int.
    public abstract androidx.paging.PagingSource<java.lang.Long, com.example.myEntity>` getPagingSource();

因此,我尝试实现我的 custom PagingSource,就像文档建议的那样。

问题是Data Refresh,因为 Room 生成的代码处理数据刷新,而我的代码无法处理这种情况。

任何建议如何实现自定义PagingSourceRoom可以处理Data Refresh

4

1 回答 1

-1

由于您有“刷新”场景并使用 Room db,我猜您正在使用 Paging3 和 network+local db 模式(使用 Room db 作为本地缓存)。

我在网络 + 本地数据库模式中遇到了类似的情况。我不确定我是否正确理解了您的问题,或者您的情况与我的情况相同,但无论如何我都会分享我所做的。

我用的是什么:

  • 分页3:3.0.0-beta01
  • 房间:2.3.0-beta02

我所做的是让 Room 库创建 PagingSource(使用 键Int),并让RemoteMediator处理所有其他情况,例如在刷新和/或追加时从网络获取数据,并在获取成功后立即将它们插入到 db 中。

dao从房间库创建 PagingSource 的功能:

@Query("SELECT * FROM article WHERE isUnread = 1")
fun getUnreadPagingSource(): PagingSource<Int, LocalArticle>

在我的例子中,我将 Repository 类定义为在其构造函数中有类,以便在创建Pagerdao时从存储库调用上面的函数。

我的自定义 RemoteMediator 类如下所示:

  • 注意:在我的例子中,没有 PREPEND 情况,所以RemoteMediator#load函数总是true在参数的值为 时loadType返回LoadType.PREPEND
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() }
    )

我希望它在某种程度上有所帮助..

其他参考:


编辑:再次阅读文档后,我发现文档明确指出:

RemoteMediator 用于将数据从网络加载到本地数据库。

于 2021-02-21T10:28:15.010 回答