Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

RemoteMediator

abstract class RemoteMediator<Key : Any, Value : Any>
kotlin.Any
   ↳ androidx.paging.RemoteMediator

Defines a set of callbacks used to incrementally load data from a remote source into a local source wrapped by a PagingSource, e.g., loading data from network into a local db cache.

A RemoteMediator is registered by passing it to Pager's constructor.

RemoteMediator allows hooking into the following events:

import androidx.room.withTransaction

/**
 * Sample RemoteMediator for a DB + Network based PagingData stream, which triggers network
 * requests to fetch additional items when a user scrolls to the end of the list of items stored
 * in DB.
 *
 * This sample loads a list of [User] items from an item-keyed Retrofit paginated source. This
 * source is "item-keyed" because we're loading the next page using information from the items
 * themselves (the ID param) as a key to fetch more data.
 */
@OptIn(ExperimentalPagingApi::class)
class ExampleRemoteMediator(
    private val query: String,
    private val database: RoomDb,
    private val networkService: ExampleBackendService
) : RemoteMediator<Int, User>() {
    val userDao = database.userDao()

    override suspend fun load(
        loadType: LoadType,
        state: PagingState<Int, User>
    ): MediatorResult {
        return try {
            // The network load method takes an optional `after=<user.id>` parameter. For every
            // page after the first, we pass the last user ID to let it continue from where it
            // left off. For REFRESH, pass `null` to load the first page.
            val loadKey = when (loadType) {
                LoadType.REFRESH -> null
                // In this example, we never need to prepend, since REFRESH will always load the
                // first page in the list. Immediately return, reporting end of pagination.
                LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
                LoadType.APPEND -> {
                    val lastItem = state.lastItemOrNull()

                    // We must explicitly check if the last item is `null` when appending,
                    // since passing `null` to networkService is only valid for initial load.
                    // If lastItem is `null` it means no items were loaded after the initial
                    // REFRESH and there are no more items to load.
                    if (lastItem == null) {
                        return MediatorResult.Success(endOfPaginationReached = true)
                    }

                    lastItem.id
                }
            }

            // 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 = networkService.searchUsers(query = query, after = loadKey)

            database.withTransaction {
                if (loadType == LoadType.REFRESH) {
                    userDao.deleteByQuery(query)
                }

                // Insert new users into database, which invalidates the current
                // PagingData, allowing Paging to present the updates in the DB.
                userDao.insertAll(response.users)
            }

            MediatorResult.Success(endOfPaginationReached = response.nextKey == null)
        } catch (e: IOException) {
            MediatorResult.Error(e)
        } catch (e: HttpException) {
            MediatorResult.Error(e)
        }
    }
}
import androidx.paging.samples.shared.RemoteKey
import androidx.room.withTransaction

/**
 * Sample RemoteMediator for a DB + Network based PagingData stream, which triggers network
 * requests to fetch additional items when a user scrolls to the end of the list of items stored
 * in DB.
 *
 * This sample loads a list of [User] via Retrofit from a page-keyed network service using
 * [String] tokens to load pages (each response has a next/previous token), and inserts them
 * into database.
 */
@OptIn(ExperimentalPagingApi::class)
class ExampleRemoteMediator(
    private val query: String,
    private val database: RoomDb,
    private val networkService: ExampleBackendService
) : RemoteMediator<Int, User>() {
    val userDao = database.userDao()
    val remoteKeyDao = database.remoteKeyDao()

    override suspend fun load(
        loadType: LoadType,
        state: PagingState<Int, User>
    ): MediatorResult {
        return try {
            // The network load method takes an optional [String] parameter. For every page
            // after the first, we pass the [String] token returned from the previous page to
            // let it continue from where it left off. For REFRESH, pass `null` to load the
            // first page.
            val loadKey = when (loadType) {
                LoadType.REFRESH -> null
                // In this example, we never need to prepend, since REFRESH will always load the
                // first page in the list. Immediately return, reporting end of pagination.
                LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
                // Query remoteKeyDao for the next RemoteKey.
                LoadType.APPEND -> {
                    val remoteKey = database.withTransaction {
                        remoteKeyDao.remoteKeyByQuery(query)
                    }

                    // We must explicitly check if the page key is `null` when appending,
                    // since `null` is only valid for initial load. If we receive `null`
                    // for APPEND, that means we have reached the end of pagination and
                    // there are no more items to load.
                    if (remoteKey.nextKey == null) {
                        return MediatorResult.Success(endOfPaginationReached = true)
                    }

                    remoteKey.nextKey
                }
            }

            // 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 = networkService.searchUsers(query, loadKey)

            // Store loaded data, and next key in transaction, so that they're always consistent
            database.withTransaction {
                if (loadType == LoadType.REFRESH) {
                    remoteKeyDao.deleteByQuery(query)
                    userDao.deleteByQuery(query)
                }

                // Update RemoteKey for this query.
                remoteKeyDao.insertOrReplace(RemoteKey(query, response.nextKey))

                // Insert new users into database, which invalidates the current
                // PagingData, allowing Paging to present the updates in the DB.
                userDao.insertAll(response.users)
            }

            MediatorResult.Success(endOfPaginationReached = response.nextKey == null)
        } catch (e: IOException) {
            MediatorResult.Error(e)
        } catch (e: HttpException) {
            MediatorResult.Error(e)
        }
    }
}

Summary

Nested classes
enum

Return type of initialize, which signals the action to take after initialize completes.

sealed

Return type of load, which determines LoadState.

Public constructors

Defines a set of callbacks used to incrementally load data from a remote source into a local source wrapped by a PagingSource, e.

Public methods
open suspend RemoteMediator.InitializeAction

Callback fired during initialization of a PagingData stream, before initial load.

abstract suspend RemoteMediator.MediatorResult
load(loadType: LoadType, state: PagingState<Key, Value>)

Callback triggered when Paging needs to request more data from a remote source due to any of the following events:

Public constructors

<init>

RemoteMediator()

Defines a set of callbacks used to incrementally load data from a remote source into a local source wrapped by a PagingSource, e.g., loading data from network into a local db cache.

A RemoteMediator is registered by passing it to Pager's constructor.

RemoteMediator allows hooking into the following events:

import androidx.room.withTransaction

/**
 * Sample RemoteMediator for a DB + Network based PagingData stream, which triggers network
 * requests to fetch additional items when a user scrolls to the end of the list of items stored
 * in DB.
 *
 * This sample loads a list of [User] items from an item-keyed Retrofit paginated source. This
 * source is "item-keyed" because we're loading the next page using information from the items
 * themselves (the ID param) as a key to fetch more data.
 */
@OptIn(ExperimentalPagingApi::class)
class ExampleRemoteMediator(
    private val query: String,
    private val database: RoomDb,
    private val networkService: ExampleBackendService
) : RemoteMediator<Int, User>() {
    val userDao = database.userDao()

    override suspend fun load(
        loadType: LoadType,
        state: PagingState<Int, User>
    ): MediatorResult {
        return try {
            // The network load method takes an optional `after=<user.id>` parameter. For every
            // page after the first, we pass the last user ID to let it continue from where it
            // left off. For REFRESH, pass `null` to load the first page.
            val loadKey = when (loadType) {
                LoadType.REFRESH -> null
                // In this example, we never need to prepend, since REFRESH will always load the
                // first page in the list. Immediately return, reporting end of pagination.
                LoadType.PREPEND -> return MediatorResult.Success(endOfPaginationReached = true)
                LoadType.APPEND -> {
                    val lastItem = state.lastItemOrNull()

                    // We must explicitly check if the last item is `null` when appending,
                    // since passing `null` to networkService is only valid for initial load.
                    // If lastItem is `null` it means no items were loaded after the initial
                    // REFRESH and there are no more items to load.
                    if (lastItem == null) {
                        return MediatorResult.Success(endOfPaginationReached = true)
                    }

                    lastItem.id
                }
            }

            // 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 = networkService.searchUsers(query = query, after = loadKey)

            database.withTransaction {
                if (loadType == LoadType.REFRESH) {
                    userDao.deleteByQuery(query)
                }

                // Insert new users into database, which invalidates the current
                // PagingData, allowing Paging to present the updates in the DB.
                userDao.insertAll(response.users)
            }

            MediatorResult.Success(endOfPaginationReached = response.nextKey == null)
        } catch (e: IOException) {
            MediatorResult.Error(e)
        } catch (e: HttpException) {
            MediatorResult.Error(e)
        }
    }
}
import androidx.paging.samples.shared.RemoteKey
import androidx.room.withTransaction

/**
 * Sample RemoteMediator for a DB + Network based PagingData stream, which triggers network
 * requests to fetch additional items when a user scrolls to the end of the list of items stored
 * in DB.
 *
 * This sample loads a list of [User] via Retrofit from a page-keyed network service using
 * [String] tokens to load pages (each response has a next/previous token), and inserts them
 * into database.
 */
@OptIn(ExperimentalPagingApi::class)
class ExampleRemoteMe