正如您在https://developer.android.com/topic/libraries/architecture/paging/v3-network-db中看到的那样,我正在使用 Android Paging 3 。当我运行应用程序时,RemoteMediator请求服务器获取列表,直到服务器上没有任何内容。
关键是我们想在用户到达列表底部时获取列表,但 RemoteMediator 一直在请求,直到获取服务器上的所有列表!
远程调解器.kt
@OptIn(ExperimentalPagingApi::class)
class ExampleRemoteMediator(
private val query: String,
private val database: RoomDb,
private val networkService: ExampleBackendService
) : RemoteMediator<Int, User>() {
val userDao = database.userDao()
val remoteKeyDao = database.remoteKeyDao()
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, User>
): MediatorResult {
return try {
// The network load method takes an optional String
// parameter. For every page after the first, pass the String
// token returned from the previous page to let it continue
// from where it left off. For REFRESH, pass null to load the
// first page.
val loadKey = when (loadType) {
LoadType.REFRESH -> null
// In this example, you never need to prepend, since REFRESH
// will always load the first page in the list. Immediately
// return, reporting end of pagination.
LoadType.PREPEND -> return MediatorResult.Success(
endOfPaginationReached = true
)
// Query remoteKeyDao for the next RemoteKey.
LoadType.APPEND -> {
val remoteKey = database.withTransaction {
remoteKeyDao.remoteKeyByQuery(query)
}
// You must explicitly check if the page key is null when
// appending, since null is only valid for initial load.
// If you receive null for APPEND, that means you have
// reached the end of pagination and there are no more
// items to load.
if (remoteKey.nextKey == null) {
return MediatorResult.Success(
endOfPaginationReached = true
)
}
remoteKey.nextKey
}
}
// Suspending network load via Retrofit. This doesn't need to
// be wrapped in a withContext(Dispatcher.IO) { ... } block
// since Retrofit's Coroutine CallAdapter dispatches on a
// worker thread.
val response = networkService.searchUsers(query, loadKey)
// Store loaded data, and next key in transaction, so that
// they're always consistent.
database.withTransaction {
if (loadType == LoadType.REFRESH) {
remoteKeyDao.deleteByQuery(query)
userDao.deleteByQuery(query)
}
// Update RemoteKey for this query.
remoteKeyDao.insertOrReplace(
RemoteKey(query, response.nextKey)
)
// Insert new users into database, which invalidates the
// current PagingData, allowing Paging to present the updates
// in the DB.
userDao.insertAll(response.users)
}
MediatorResult.Success(
endOfPaginationReached = response.nextKey == null
)
} catch (e: IOException) {
MediatorResult.Error(e)
} catch (e: HttpException) {
MediatorResult.Error(e)
}
}
}
LoadType.PREPEND和LoadType.APPEND不断调用!