Nikita Khlebushkin
07/13/2021, 11:29 PMinvalidate()
method of PagingSource, then it starts spamming load
method of PagingSource (and doesn't even wait until the job is finished, cancels it and starts anew). This is the stacktrace:
2021-07-14 02:23:46.189 15215-15254/com.xlebnick.kitties.debug D/OkHttp: --> GET <https://myapi.com/v1/images/search?page=0&limit=24&order=ASC>
2021-07-14 02:23:46.189 15215-15254/com.xlebnick.kitties.debug D/OkHttp: x-api-key: 9b7e282d-2a67-4c7b-a9fd-3f3e4056e949
2021-07-14 02:23:46.189 15215-15254/com.xlebnick.kitties.debug D/OkHttp: --> END GET
2021-07-14 02:23:46.189 15215-15254/com.xlebnick.kitties.debug D/OkHttp: <-- HTTP FAILED: java.io.IOException: Canceled
2021-07-14 02:23:46.189 15215-15215/com.xlebnick.kitties.debug W/System.err: kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@6c3004
And this is my implementation:
class KittiesPagingSource(
private val repository: Repository,
var breedFilter: Breed? = null,
var likedKitties: List<Like> = listOf()
) : PagingSource<Int, Kitty>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Kitty> {
return try {
// Start refresh at page 1 if undefined.
val nextPage = params.key ?: 1
val filters = if (breedFilter != null) listOf(breedFilter!!) else null
var kitties: List<KittyRemoteModel> = listOf()
try {
kitties = repository.fetchKitties(nextPage, KITTIES_PAGE_SIZE, filters)
} catch (e: Throwable) {
e.printStackTrace()
}
val newKitties = kitties.map { kitty ->
kitty.asKitty(likedKitties.any { it.imageId == kitty.id })
}
LoadResult.Page(
data = newKitties,
prevKey = if (nextPage == 1) null else nextPage - 1,
nextKey = if (newKitties.isEmpty()) null else nextPage + 1
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
override fun getRefreshKey(state: PagingState<Int, Kitty>): Int? {
return state.anchorPosition?.let {
if (it < state.config.initialLoadSize) {
// if anchor position is less than initial loading count then download from the beginning
0
} else {
// otherwise load a page around anchorPosition using initialLoadSize
(it - state.config.initialLoadSize / 2).coerceAtLeast(0)
}
}
}
}
private val kittiesPagingFactory = InvalidatingPagingSourceFactory {
KittiesPagingSource(repository, breedFilter, likedKitties.value ?: listOf())
}
private val kittiesPager =
Pager(PagingConfig(pageSize = 6), pagingSourceFactory = kittiesPagingFactory)
val kitties: Flow<PagingData<Kitty>> = kittiesPager
.flow
.cachedIn(viewModelScope)
What am I doing wrong?dustin
07/13/2021, 11:35 PMdustin
07/13/2021, 11:35 PMdustin
07/13/2021, 11:35 PMNikita Khlebushkin
07/13/2021, 11:38 PMNikita Khlebushkin
07/13/2021, 11:39 PMNikita Khlebushkin
07/13/2021, 11:40 PMkittiesPagingFactory.invalidate()
, and it's been only fired onceNikita Khlebushkin
07/14/2021, 12:00 AMephemient
07/14/2021, 3:12 AMDustin Lam
07/14/2021, 5:11 AMNikita Khlebushkin
07/14/2021, 5:27 AMNikita Khlebushkin
07/14/2021, 5:28 AMis it looping between prepend and appendIf I understand the question correctly, then yes, because it keeps updating the flow, and therefore, the RecyclerView
Nikita Khlebushkin
07/14/2021, 5:34 AMload
is always androidx.paging.PagingSource$LoadParams$Refresh
Nikita Khlebushkin
07/14/2021, 5:34 AMDustin Lam
07/14/2021, 6:45 AMDustin Lam
07/14/2021, 6:46 AMNikita Khlebushkin
07/14/2021, 6:52 AMNikita Khlebushkin
07/14/2021, 7:18 AMNikita Khlebushkin
07/14/2021, 10:51 AMdustin
07/15/2021, 6:35 PMdustin
07/15/2021, 6:36 PMdustin
07/15/2021, 6:36 PMpublic class InvalidatingPagingSourceFactory<Key : Any, Value : Any>(
private val pagingSourceFactory: () -> PagingSource<Key, Value>
) : () -> PagingSource<Key, Value> {
private val pagingSources = mutableListOf<PagingSource<Key, Value>>()
override fun invoke(): PagingSource<Key, Value> {
return pagingSourceFactory().also { pagingSources.add(it) }
}
public fun invalidate() {
for (pagingSource in pagingSources.toList()) {
if (!pagingSource.invalid) {
pagingSource.invalidate()
}
}
pagingSources.removeAll { it.invalid }
}
}
dustin
07/15/2021, 6:37 PMNikita Khlebushkin
07/16/2021, 6:06 AM