Status Update
Comments
du...@google.com <du...@google.com> #2
th...@gmail.com <th...@gmail.com> #3
Thanks for reporting this!
ap...@google.com <ap...@google.com> #4
Same here, any update? Stuck at alpha02 for a long time.
du...@google.com <du...@google.com> #5
A few notes:
- Should be using
viewLifecyclerOwner.lifecycleScope
instead of justlifecycleScope
in aFragment
. - Cancellation is happening as a result of the fragment automatically paging over when they are initially created / added to viewpager2 (this is expected as far as I can tell)
- Right now
RemoteMediator
kind of acts as a dumb callback wheneverPagingSource
runs out of items to load, soREFRESH
error doesn't prevent remotePREPEND
/APPEND
. It's not clear to me yet whether it should or if we should change guidance to just handleAPPEND
. This is due to us changing the behavior of Remote REFRESH after the codelab was produced, so I'm very sorry for that. REFRESH is meant to handle any init that needs to happen, technically the initial network page fetch happens as a result of running out of items on the APPEND side.
e.g., Here is a modified sample from the opening post / #1's repro project that fixes the issue:
PageKeyedRemoteMediator.kt
override suspend fun load(
loadType: LoadType,
state: PagingState<Int, RedditPost>
): MediatorResult {
try {
// Get the closest item from PagingState that we want to load data around.
val loadKey = when (loadType) {
REFRESH -> {
db.withTransaction {
postDao.deleteBySubreddit(subredditName)
remoteKeyDao.deleteBySubreddit(subredditName)
}
return MediatorResult.Success(endOfPaginationReached = false)
}
PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
APPEND -> {
// Query DB for SubredditRemoteKey for the subreddit.
// SubredditRemoteKey is a wrapper object we use to keep track of page keys we
// receive from the Reddit API to fetch the next or previous page.
val remoteKey = db.withTransaction {
remoteKeyDao.remoteKeyByPost(subredditName)
}
when {
remoteKey == null -> null
// We must explicitly check if the page key is null after initial load, since the
// Reddit API informs the end of the list by returning null for page key, but
// passing a null key to Reddit API will fetch the initial page.
remoteKey.nextPageKey == null -> {
return MediatorResult.Success(endOfPaginationReached = true)
}
else -> remoteKey.nextPageKey
}
}
}
val data = redditApi.getTop(
subreddit = subredditName,
after = loadKey,
before = null,
limit = state.config.pageSize * 3
).data
val items = data.children.map { it.data }
db.withTransaction {
remoteKeyDao.insert(SubredditRemoteKey(subredditName, data.after))
postDao.insertAll(items)
}
return MediatorResult.Success(endOfPaginationReached = items.isEmpty())
} catch (e: IOException) {
return MediatorResult.Error(e)
} catch (e: HttpException) {
return MediatorResult.Error(e)
} catch (e: CancellationException) {
Log.d("RemoteMediator","$subredditName $loadType canceled")
throw e
}
}
du...@google.com <du...@google.com> #6
Will keep this bug open to track the decision on blocking RemoteMediator
PREPEND
/ APPEND
after remote REFRESH error and any possible updates to the Codelab / Github samples.
The inconvenience of blocking on REFRESH is going to surface via needing to call retry()
, but it's possible there's something better we can do to handle cancellation more gracefully since we don't want to keep creating new PagingData
and also support loading in the background. (the thing to change to control this is when you start collecting from Pager.flow
, and the scope collection happens in).
th...@gmail.com <th...@gmail.com> #7
I have a question about the modified sample. Shouldn't deleteByXXX
be moved to after redditApi
execute successfully?
The UI side will see blink twice in this sample: Show db cache first then disappeared, show data again after redditApi
successful and insert data. The user experience is pretty bad.
Description
Version used: 3.0.0-alpha01
I have followed codelabs paging 3 tutorial. I have implemented paging from network and database.
This is the repository provided by codelabs tutorial :-
I have founded 2 issues in Paging 3.
1. Application get crashed when Recylerview reach at end(last page).
Inside GithubRemoteMediator.kt
I have set val endOfPaginationReached = page > 2 to allow maximum 2 pages for testing.
So, the problem is when I reach at the last page of list, application get crashed as remoteKeys.nextKey is null(as we have set nextKey=null for last page of list).
2. Offline cache broken
How to support caching when application is open without internet connection. currently it is showing retry button. How to show previously loaded data. I have tried to fix this by removing
// clear all tables in the database
if (loadType == LoadType.REFRESH) {
repoDatabase.remoteKeysDao().clearRemoteKeys()
repoDatabase.reposDao().clearRepos()
}
as this will now not gone delete data from database.
But still Pager does not load data available.
So how I can fix this problem?
Is there any way of detecting end of paging?
Why Pager is not returning data available in database.