CachedPagingDataKt

public final class CachedPagingDataKt


Summary

Public methods

static final @NonNull Flow<@NonNull PagingData<@NonNull T>>
<T extends Object> cachedIn(
    @NonNull Flow<@NonNull PagingData<@NonNull T>> receiver,
    @NonNull CoroutineScope scope
)

Caches the PagingData such that any downstream collection from this flow will share the same PagingData.

Public methods

cachedIn

@NonNull
public static final Flow<@NonNull PagingData<@NonNull T>> <T extends Object> cachedIn(
    @NonNull Flow<@NonNull PagingData<@NonNull T>> receiver,
    @NonNull CoroutineScope scope
)

Caches the PagingData such that any downstream collection from this flow will share the same PagingData.

The flow is kept active as long as the given scope is active. To avoid leaks, make sure to use a scope that is already managed (like a ViewModel scope) or manually cancel it when you don't need paging anymore.

A common use case for this caching is to cache PagingData in a ViewModel. This can ensure that, upon configuration change (e.g. rotation), then new Activity will receive the existing data immediately rather than fetching it from scratch.

Calling cachedIn is required to allow calling androidx.paging.AsyncPagingDataAdapter on the same instance of PagingData emitted by Pager or any of its transformed derivatives, as reloading data from scratch on the same generation of PagingData is an unsupported operation.

Note that this does not turn the Flow<PagingData> into a hot stream. It won't execute any unnecessary code unless it is being collected.

import androidx.activity.viewModels
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import androidx.paging.map

class MyViewModel : ViewModel() {
    val flow = Pager(
        config = PagingConfig(pageSize = 40),
        pagingSourceFactory = pagingSourceFactory
    ).flow
        // Loads and transformations before the cachedIn operation will be cached, so that
        // multiple observers get the same data. This is true either for simultaneous
        // observers, or e.g. an Activity re-subscribing after being recreated
        .cachedIn(viewModelScope)
}

class MyActivity : AppCompatActivity() {
    val pagingAdapter = MyPagingAdapter()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val viewModel by viewModels<MyViewModel>()

        lifecycleScope.launch {
            viewModel.flow
                // Any transformations after the ViewModel's cachedIn step will not be cached,
                // and will instead by re-run immediately on Activity re-creation.
                .map { pagingData ->
                    // example un-cached transformation
                    pagingData.map { UiModel(it) }
                }
                .collectLatest {
                    pagingAdapter.submitData(it)
                }
        }
    }
}
Parameters
@NonNull CoroutineScope scope

The coroutine scope where this page cache will be kept alive.