I am writing a toy Android app using Kotlin flow and Android Paging 3 library. The app calls some remote API to get a list of photos, and display them using a RecyclerView
with a PagingDataAdapter
.
I find that the code after pagingAdapter.submitData()
is not executed.
Here is the code snippet (this function is in a Fragment
):
fun refreshList() {
lifecycleScope.launch {
photosViewModel.listPhotos().collect {
// `it` is PagingData<Photo>
pagingAdapter.submitData(it)
Log.e(TAG, "After submitData")
}
}
}
The log After submitData
is not printed.
However, if I put the logging in front of the pagingAdapter.submitData()
line, it is printed, like this:
fun refreshList() {
lifecycleScope.launch {
photosViewModel.listPhotos().collect {
// `it` is PagingData<Photo>
Log.e(TAG, "Before submitData")
pagingAdapter.submitData(it)
}
}
}
The log Before submitData
is printed with no problem.
Why does this happen, please?
.submitData
is a suspending function which does not return until invalidation or refresh. As long as Paging is actively loading (collecting) from the PagingData
you provided, it will not finish. This is why it must be done in a launched job.
For the same reason, make sure to use collectLatest
instead of collect
to make sure you cancel and start displaying new generations
as soon as possible.