Is background threading managed automatically with PagingData
as it is with PagedList
, and then returned on the main thread?
From the logs below, it appears PagingData
is not run on the backgroud thread in the Paging 3 library compared to PagedList
in Paging 2's library.
Expect (Based on the Paging Codelab sample)
- GithubPagingSource
override suspend fun load(...)
to run on an IO thread. - SearchRepositoriesActivity
viewModel.searchRepo(query).collectLatest { ... }
to run on the main thread.
Observe
- Both GithubPagingSource
override suspend fun load(...)
and SearchRepositoriesActivityviewModel.searchRepo(query).collectLatest { ... }
run on the main thread.
Paging 2
Threading is handled on the background by PagedList
with toLiveData
according to the documentation.
If you use LivePagedListBuilder to get a LiveData, it will initialize PagedLists on a background thread for you.
Paging 3
The Paging 3 documentation does not mention how threading is managed. However, from the logs, PagingSource
appears to be running the network request on a main thread and returning the PagingData
on a main thread.
My Sample Code
I've recreated the Codelab pattern in the CryptoTweets sample app app-simple module.
FeedPagingSource.kt
class FeedPagingSource : PagingSource<Int, Tweet>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Tweet> {
try {
val page = params.key ?: 1
val nextPage = page + 1
val tweets = Injection.feedService.getTweets(...)
println("Thread: FeedPagingSource ${Thread.currentThread().name}")
Log.v(LOG_TAG, "load success: ${tweets}")
return LoadResult.Page(...)
} catch (error: Exception) {
...
}
}
}
FeedRepository.kt
class FeedRepository {
fun initFeed() = Pager(
config = PagingConfig(pageSize = FEED_PAGEDLIST_SIZE),
pagingSourceFactory = { FeedPagingSource() }
).flow
}
FeedViewModel.kt
repository.initFeed().onEach {
println("Thread: FeedViewModel ${Thread.currentThread().name}")
_feed.value = it
}.launchIn(viewModelScope)
Attempted Solution
In order to run the PagingSource
on a background thread, the flow is initiated on Dispatchers.IO
. However, the log still shows PagingSource
runs on the main thread in FeedPagingSource.kt.
FeedViewModel.kt
repository.initFeed().onEach {
println("Thread: FeedViewModel ${Thread.currentThread().name}")
_feed.value = it
}.flowOn(Dispatchers.IO).launchIn(viewModelScope)