# PagingSource

Artifact: [androidx.paging:paging-common](https://developer.android.com/jetpack/androidx/releases/paging) [View Source](https://cs.android.com/search?q=file:androidx/paging/PagingSource.kt+class:androidx.paging.PagingSource) Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

*** ** * ** ***


```
public abstract class PagingSource<Key extends Object, Value extends Object>
```

<br />

Known direct subclasses [ListenableFuturePagingSource](https://developer.android.com/reference/androidx/paging/ListenableFuturePagingSource), [RxPagingSource](https://developer.android.com/reference/androidx/paging/rxjava2/RxPagingSource), [RxPagingSource](https://developer.android.com/reference/androidx/paging/rxjava3/RxPagingSource)

|---|---|
| `https://developer.android.com/reference/androidx/paging/ListenableFuturePagingSource` | `https://guava.dev/releases/snapshot-android/api/docs/com/google/common/util/concurrent/ListenableFuture.html`-based compatibility wrapper around `https://developer.android.com/reference/androidx/paging/PagingSource`'s suspending APIs. |
| `https://developer.android.com/reference/androidx/paging/rxjava2/RxPagingSource` | Rx-based compatibility wrapper around `https://developer.android.com/reference/androidx/paging/PagingSource`'s suspending APIs. |
| `https://developer.android.com/reference/androidx/paging/rxjava3/RxPagingSource` | Rx-based compatibility wrapper around `https://developer.android.com/reference/androidx/paging/PagingSource`'s suspending APIs. |

*** ** * ** ***

Base class for an abstraction of pageable static data from some source, where loading pages of data is typically an expensive operation. Some examples of common `https://developer.android.com/reference/androidx/paging/PagingSource`s might be from network or from a database.

An instance of a `https://developer.android.com/reference/androidx/paging/PagingSource` is used to load pages of data for an instance of `https://developer.android.com/reference/androidx/paging/PagingData`.

A `https://developer.android.com/reference/androidx/paging/PagingData` can grow as it loads more data, but the data loaded cannot be updated. If the underlying data set is modified, a new `https://developer.android.com/reference/androidx/paging/PagingSource` / `https://developer.android.com/reference/androidx/paging/PagingData` pair must be created to represent an updated snapshot of the data.

### Loading Pages

`https://developer.android.com/reference/androidx/paging/PagingData` queries data from its `https://developer.android.com/reference/androidx/paging/PagingSource` in response to loading hints generated as the user scrolls in a `RecyclerView`.

To control how and when a `https://developer.android.com/reference/androidx/paging/PagingData` queries data from its `https://developer.android.com/reference/androidx/paging/PagingSource`, see `https://developer.android.com/reference/androidx/paging/PagingConfig`, which defines behavior such as `https://developer.android.com/reference/androidx/paging/PagingConfig#pageSize()` and `https://developer.android.com/reference/androidx/paging/PagingConfig#prefetchDistance()`.

### Updating Data

A `https://developer.android.com/reference/androidx/paging/PagingSource` / `https://developer.android.com/reference/androidx/paging/PagingData` pair is a snapshot of the data set. A new `https://developer.android.com/reference/androidx/paging/PagingData` / `https://developer.android.com/reference/androidx/paging/PagingData` must be created if an update occurs, such as a reorder, insert, delete, or content update occurs. A `https://developer.android.com/reference/androidx/paging/PagingSource` must detect that it cannot continue loading its snapshot (for instance, when Database query notices a table being invalidated), and call `https://developer.android.com/reference/androidx/paging/PagingSource#invalidate()`. Then a new `https://developer.android.com/reference/androidx/paging/PagingSource` / `https://developer.android.com/reference/androidx/paging/PagingData` pair would be created to represent data from the new state of the database query.

### Presenting Data to UI

To present data loaded by a `https://developer.android.com/reference/androidx/paging/PagingSource` to a `RecyclerView`, create an instance of `https://developer.android.com/reference/androidx/paging/Pager`, which provides a stream of `https://developer.android.com/reference/androidx/paging/PagingData` that you may collect from and submit to a androidx.paging.PagingDataAdapter.

```kotlin
import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingState

/**
 * Sample page-keyed PagingSource, which uses Int page number to load pages.
 *
 * Loads Items from network requests via Retrofit to a backend service.
 *
 * Note that the key type is Int, since we're using page number to load a page.
 */
class MyPagingSource(val myBackend: MyBackendService) : PagingSource<Int, Item>() {
    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {

        // Retrofit calls that return the body type throw either IOException for network
        // failures, or HttpException for any non-2xx HTTP status codes. This code reports all
        // errors to the UI, but you can inspect/wrap the exceptions to provide more context.
        return try {
            // Key may be null during a refresh, if no explicit key is passed into Pager
            // construction. Use 0 as default, because our API is indexed started at index 0
            val pageNumber = params.key ?: 0

            // Suspending network load via Retrofit. This doesn't need to be wrapped in a
            // withContext(Dispatcher.IO) { ... } block since Retrofit's Coroutine
            // CallAdapter dispatches on a worker thread.
            val response = myBackend.searchItems(pageNumber)

            // Since 0 is the lowest page number, return null to signify no more pages should
            // be loaded before it.
            val prevKey = if (pageNumber > 0) pageNumber - 1 else null

            // This API defines that it's out of data when a page returns empty. When out of
            // data, we return `null` to signify no more pages should be loaded
            val nextKey = if (response.items.isNotEmpty()) pageNumber + 1 else null
            LoadResult.Page(data = response.items, prevKey = prevKey, nextKey = nextKey)
        } catch (e: IOException) {
            LoadResult.Error(e)
        } catch (e: HttpException) {
            LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, Item>): Int? {
        return state.anchorPosition?.let {
            state.closestPageToPosition(it)?.prevKey?.plus(1)
                ?: state.closestPageToPosition(it)?.nextKey?.minus(1)
        }
    }
}
```

```kotlin
import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingState

/**
 * Sample item-keyed [PagingSource], which uses String tokens to load pages.
 *
 * Loads Items from network requests via Retrofit to a backend service.
 */
class MyPagingSource(val myBackend: MyBackendService) : PagingSource<String, Item>() {
    override suspend fun load(params: LoadParams<String>): LoadResult<String, Item> {
        // Retrofit calls that return the body type throw either IOException for network
        // failures, or HttpException for any non-2xx HTTP status codes. This code reports all
        // errors to the UI, but you can inspect/wrap the exceptions to provide more context.
        return try {
            // Suspending network load via Retrofit. This doesn't need to be wrapped in a
            // withContext(Dispatcher.IO) { ... } block since Retrofit's Coroutine
            // CallAdapter dispatches on a worker thread.
            val response = myBackend.searchItems(params.key)
            LoadResult.Page(
                data = response.items,
                prevKey = response.prev,
                nextKey = response.next,
            )
        } catch (e: IOException) {
            LoadResult.Error(e)
        } catch (e: HttpException) {
            LoadResult.Error(e)
        }
    }

    override fun getRefreshKey(state: PagingState<String, Item>): String? {
        return state.anchorPosition?.let { state.closestItemToPosition(it)?.id }
    }
}
```

| Parameters |
|---|---|
| `<Key extends https://developer.android.com/reference/java/lang/Object.html>` | Type of key which define what data to load. E.g. `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` to represent either a page number or item position, or `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html` if your network uses Strings as next tokens returned with each response. |
| `<Value extends https://developer.android.com/reference/java/lang/Object.html>` | Type of data loaded in by this `https://developer.android.com/reference/androidx/paging/PagingSource`. E.g., the type of data that will be passed to a androidx.paging.PagingDataAdapter to be displayed in a `RecyclerView`. |

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/paging/Pager` |   |

## Summary

| ### Nested types |
|---|
| `public sealed class https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams<Key extends https://developer.android.com/reference/java/lang/Object.html>` Params for a load request on a `https://developer.android.com/reference/androidx/paging/PagingSource` from `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)`. |
| `public final class https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams.Append<Key extends https://developer.android.com/reference/java/lang/Object.html> extends https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams<@https://developer.android.com/reference/androidx/annotation/NonNull Key>` Params to load a page of data from a `https://developer.android.com/reference/androidx/paging/PagingSource` via `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` to be appended to the end of the list. |
| `public final class https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams.Prepend<Key extends https://developer.android.com/reference/java/lang/Object.html> extends https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams<@https://developer.android.com/reference/androidx/annotation/NonNull Key>` Params to load a page of data from a `https://developer.android.com/reference/androidx/paging/PagingSource` via `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` to be prepended to the start of the list. |
| `public final class https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams.Refresh<Key extends https://developer.android.com/reference/java/lang/Object.html> extends https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams<@https://developer.android.com/reference/androidx/annotation/NonNull Key>` Params for an initial load request on a `https://developer.android.com/reference/androidx/paging/PagingSource` from `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` or a refresh triggered by `https://developer.android.com/reference/androidx/paging/PagingSource#invalidate()`. |
| `public sealed class https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult<Key extends https://developer.android.com/reference/java/lang/Object.html, Value extends https://developer.android.com/reference/java/lang/Object.html>` Result of a load request from `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)`. |
| `public final class https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult.Error<Key extends https://developer.android.com/reference/java/lang/Object.html, Value extends https://developer.android.com/reference/java/lang/Object.html> extends https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult<@https://developer.android.com/reference/androidx/annotation/NonNull Key, @https://developer.android.com/reference/androidx/annotation/NonNull Value>` Error result object for `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)`. |
| `public final class https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult.Invalid<Key extends https://developer.android.com/reference/java/lang/Object.html, Value extends https://developer.android.com/reference/java/lang/Object.html> extends https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult<@https://developer.android.com/reference/androidx/annotation/NonNull Key, @https://developer.android.com/reference/androidx/annotation/NonNull Value>` Invalid result object for `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` |
| `public final class https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult.Page<Key extends https://developer.android.com/reference/java/lang/Object.html, Value extends https://developer.android.com/reference/java/lang/Object.html> extends https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult<@https://developer.android.com/reference/androidx/annotation/NonNull Key, @https://developer.android.com/reference/androidx/annotation/NonNull Value> implements https://developer.android.com/reference/java/lang/Iterable.html<@https://developer.android.com/reference/androidx/annotation/NonNull Value>` Success result object for `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)`. |

| ### Public constructors |
|---|
| `<Key extends https://developer.android.com/reference/java/lang/Object.html, Value extends https://developer.android.com/reference/java/lang/Object.html> https://developer.android.com/reference/androidx/paging/PagingSource#PagingSource()()` |

| ### Public methods |
|---|---|
| `final boolean` | `https://developer.android.com/reference/androidx/paging/PagingSource#getInvalid()()` Whether this `https://developer.android.com/reference/androidx/paging/PagingSource` has been invalidated, which should happen when the data this `https://developer.android.com/reference/androidx/paging/PagingSource` represents changes since it was first instantiated. |
| `boolean` | `https://developer.android.com/reference/androidx/paging/PagingSource#getJumpingSupported()()` `true` if this `https://developer.android.com/reference/androidx/paging/PagingSource` supports jumping, `false` otherwise. |
| `boolean` | `https://developer.android.com/reference/androidx/paging/PagingSource#getKeyReuseSupported()()` `true` if this `https://developer.android.com/reference/androidx/paging/PagingSource` expects to re-use keys to load distinct pages without a call to `https://developer.android.com/reference/androidx/paging/PagingSource#invalidate()`, `false` otherwise. |
| `abstract Key` | `https://developer.android.com/reference/androidx/paging/PagingSource#getRefreshKey(androidx.paging.PagingState)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/paging/PagingState<@https://developer.android.com/reference/androidx/annotation/NonNull Key, @https://developer.android.com/reference/androidx/annotation/NonNull Value> state)` Provide a `https://developer.android.com/reference/androidx/paging/PagingSource` used for the initial `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` for the next `https://developer.android.com/reference/androidx/paging/PagingSource` due to invalidation of this `https://developer.android.com/reference/androidx/paging/PagingSource`. |
| `final void` | `https://developer.android.com/reference/androidx/paging/PagingSource#invalidate()()` Signal the `https://developer.android.com/reference/androidx/paging/PagingSource` to stop loading. |
| `abstract @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult<@https://developer.android.com/reference/androidx/annotation/NonNull Key, @https://developer.android.com/reference/androidx/annotation/NonNull Value>` | `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams<@https://developer.android.com/reference/androidx/annotation/NonNull Key> params)` Loading API for `https://developer.android.com/reference/androidx/paging/PagingSource`. |
| `final void` | `https://developer.android.com/reference/androidx/paging/PagingSource#registerInvalidatedCallback(kotlin.Function0)( @https://developer.android.com/reference/androidx/annotation/NonNull Function0<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html> onInvalidatedCallback )` Add a callback to invoke when the `https://developer.android.com/reference/androidx/paging/PagingSource` is first invalidated. |
| `final void` | `https://developer.android.com/reference/androidx/paging/PagingSource#unregisterInvalidatedCallback(kotlin.Function0)( @https://developer.android.com/reference/androidx/annotation/NonNull Function0<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html> onInvalidatedCallback )` Remove a previously added invalidate callback. |

## Public constructors

### PagingSource

```
public <Key extends Object, Value extends Object> PagingSource()
```

| Parameters |
|---|---|
| `<Key extends https://developer.android.com/reference/java/lang/Object.html>` | Type of key which define what data to load. E.g. `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html` to represent either a page number or item position, or `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html` if your network uses Strings as next tokens returned with each response. |
| `<Value extends https://developer.android.com/reference/java/lang/Object.html>` | Type of data loaded in by this `https://developer.android.com/reference/androidx/paging/PagingSource`. E.g., the type of data that will be passed to a androidx.paging.PagingDataAdapter to be displayed in a `RecyclerView`. |

## Public methods

### getInvalid

Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

```
public final boolean getInvalid()
```

Whether this `https://developer.android.com/reference/androidx/paging/PagingSource` has been invalidated, which should happen when the data this `https://developer.android.com/reference/androidx/paging/PagingSource` represents changes since it was first instantiated.

### getJumpingSupported

Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

```
public boolean getJumpingSupported()
```

`true` if this `https://developer.android.com/reference/androidx/paging/PagingSource` supports jumping, `false` otherwise.

Override this to `true` if pseudo-fast scrolling via jumps is supported.

A jump occurs when a `RecyclerView` scrolls through a number of placeholders defined by `https://developer.android.com/reference/androidx/paging/PagingConfig#jumpThreshold()` and triggers a load with `https://developer.android.com/reference/androidx/paging/LoadType#REFRESH`.

`https://developer.android.com/reference/androidx/paging/PagingSource`s that support jumps should override `https://developer.android.com/reference/androidx/paging/PagingSource#getRefreshKey(androidx.paging.PagingState)` to return a `https://developer.android.com/reference/androidx/paging/PagingSource` that would load data fulfilling the viewport given a user's current `https://developer.android.com/reference/androidx/paging/PagingState#anchorPosition()`.

To support jumping, the `https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult.Page` returned from this PagingSource must implement `https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult.Page#itemsBefore()` and `https://developer.android.com/reference/androidx/paging/PagingSource.LoadResult.Page#itemsAfter()` to notify Paging the boundaries within which it can jump.

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/paging/PagingConfig#jumpThreshold()` |   |

### getKeyReuseSupported

Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

```
public boolean getKeyReuseSupported()
```

`true` if this `https://developer.android.com/reference/androidx/paging/PagingSource` expects to re-use keys to load distinct pages without a call to `https://developer.android.com/reference/androidx/paging/PagingSource#invalidate()`, `false` otherwise.

### getRefreshKey

Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

```
public abstract Key getRefreshKey(@NonNull PagingState<@NonNull Key, @NonNull Value> state)
```

Provide a `https://developer.android.com/reference/androidx/paging/PagingSource` used for the initial `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` for the next `https://developer.android.com/reference/androidx/paging/PagingSource` due to invalidation of this `https://developer.android.com/reference/androidx/paging/PagingSource`. The `https://developer.android.com/reference/androidx/paging/PagingSource` is provided to `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` via `https://developer.android.com/reference/androidx/paging/PagingSource.LoadParams#key()`.

The `https://developer.android.com/reference/androidx/paging/PagingSource` returned by this method should cause `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` to load enough items to fill the viewport *around* the last accessed position, allowing the next generation to transparently animate in. The last accessed position can be retrieved via `https://developer.android.com/reference/androidx/paging/PagingState#anchorPosition()`, which is typically the *top-most* or *bottom-most* item in the viewport due to access being triggered by binding items as they scroll into view.

For example, if items are loaded based on integer position keys, you can return `( (state.anchorPosition ?: 0) - state.config.initialLoadSize / 2).coerceAtLeast(0)`.

Alternately, if items contain a key used to load, get the key from the item in the page at index `https://developer.android.com/reference/androidx/paging/PagingState#anchorPosition()` then try to center it based on `state.config.initialLoadSize`.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/paging/PagingState<@https://developer.android.com/reference/androidx/annotation/NonNull Key, @https://developer.android.com/reference/androidx/annotation/NonNull Value> state` | `https://developer.android.com/reference/androidx/paging/PagingState` of the currently fetched data, which includes the most recently accessed position in the list via `https://developer.android.com/reference/androidx/paging/PagingState#anchorPosition()`. |

| Returns |
|---|---|
| `Key` | `https://developer.android.com/reference/androidx/paging/PagingSource` passed to `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` after invalidation used for initial load of the next generation. The `https://developer.android.com/reference/androidx/paging/PagingSource` returned by `https://developer.android.com/reference/androidx/paging/PagingSource#getRefreshKey(androidx.paging.PagingState)` should load pages centered around user's current viewport. If the correct `https://developer.android.com/reference/androidx/paging/PagingSource` cannot be determined, `null` can be returned to allow `https://developer.android.com/reference/androidx/paging/PagingSource#load(androidx.paging.PagingSource.LoadParams)` decide what default key to use. |

### invalidate

Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

```
public final void invalidate()
```

Signal the `https://developer.android.com/reference/androidx/paging/PagingSource` to stop loading.

This method is idempotent. i.e., If `https://developer.android.com/reference/androidx/paging/PagingSource#invalidate()` has already been called, subsequent calls to this method should have no effect.

### load

```
public abstract @NonNull PagingSource.LoadResult<@NonNull Key, @NonNull Value> load(@NonNull PagingSource.LoadParams<@NonNull Key> params)
```

Loading API for `https://developer.android.com/reference/androidx/paging/PagingSource`.

Implement this method to trigger your async load (e.g. from database or network).

### registerInvalidatedCallback

Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

```
public final void registerInvalidatedCallback(
    @NonNull Function0<Unit> onInvalidatedCallback
)
```

Add a callback to invoke when the `https://developer.android.com/reference/androidx/paging/PagingSource` is first invalidated.

Once invalidated, a `https://developer.android.com/reference/androidx/paging/PagingSource` will not become valid again.

A `https://developer.android.com/reference/androidx/paging/PagingSource` will only invoke its callbacks once - the first time `https://developer.android.com/reference/androidx/paging/PagingSource#invalidate()` is called, on that thread.

If this `https://developer.android.com/reference/androidx/paging/PagingSource` is already invalid, the provided `https://developer.android.com/reference/androidx/paging/PagingSource#registerInvalidatedCallback(kotlin.Function0)` will be triggered immediately.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull Function0<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html> onInvalidatedCallback` | The callback that will be invoked on thread that invalidates the `https://developer.android.com/reference/androidx/paging/PagingSource`. |

### unregisterInvalidatedCallback

Added in [3.0.0](https://developer.android.com/jetpack/androidx/releases/paging#3.0.0)

```
public final void unregisterInvalidatedCallback(
    @NonNull Function0<Unit> onInvalidatedCallback
)
```

Remove a previously added invalidate callback.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull Function0<https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html> onInvalidatedCallback` | The previously added callback. |