Библиотека подкачки, хранящая в базе данных помещений только значения, полученные первыми.Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Библиотека подкачки, хранящая в базе данных помещений только значения, полученные первыми.

Сообщение Anonymous »

У меня есть приложение, в котором я реализовал библиотеку подкачки 3 для извлечения данных из API и их разбиения на страницы, она отлично работает при извлечении данных, следующая реализация заключалась в сохранении извлеченных данных в базе данных комнаты, я создал класс Remotemediator и написал код для хранения данных, но проблема в том, что он хранит только значения первой страницы (например, в моем случае я использую API базы данных фильмов, на каждой полученной странице содержится 20 фильмов, а страниц много), в моем случае он сохраняет только первые 20 фильмов, даже когда я прокручиваю, они не сохраняют больше данных, я реализовал тот же самый код, но, похоже, это так, я столкнулся с этим в более старом проекте, а теперь и в этом, мне нужна помощь, спасибо заранее.
  • Кино Дао
@Dao
interface MoviesDao {

@Query("SELECT * FROM movieTable ORDER BY id")
fun getMovies() : PagingSource

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMovies(result: List)

@Query("DELETE FROM movieTable")
suspend fun clearMovies()

}
  • RemoteKeys Dao
@Dao
interface RemoteKeysDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(remoteKey: List)

@Query("SELECT * FROM remote_keys WHERE movieId = :movieId")
suspend fun remoteKeysRepoId(movieId : Long): RemoteKeys?

@Query("DELETE FROM remote_keys")
suspend fun clearRemoteKeys()

}
  • Класс RemoteMediator
private var MOVIES_API_STARTING_PAGE_INDEX = 1
@ExperimentalPagingApi
class MoviesMediator(
private var authResponse: AuthResponse,
private var movieDatabase: MovieDatabase
) : RemoteMediator() {

override suspend fun load(loadType: LoadType, state: PagingState): MediatorResult {
val page = when (loadType) {
LoadType.REFRESH -> {
val remoteKeys = getRemoteKeyClosestToCurrentPosition(state)
remoteKeys?.nextKey?.minus(1) ?: MOVIES_API_STARTING_PAGE_INDEX
}
LoadType.PREPEND -> {
val remoteKeys = getRemoteKeyForFirstItem(state)
val prevKey = remoteKeys?.prevKey
if (prevKey == null) {
return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
prevKey
}
LoadType.APPEND -> {
val remoteKeys = getRemoteKeyForLastItem(state)
val nextKey = remoteKeys?.nextKey
if (nextKey == null) {
return MediatorResult.Success(endOfPaginationReached = remoteKeys != null)
}
nextKey
}
}
try {
val response = authResponse.getMovies(Constants.API_KEY, Constants.LANGUAGE, page).results

val endOfPagination = response.isEmpty()
movieDatabase.withTransaction {
// clear all tables in the database
if (loadType == LoadType.REFRESH) {
movieDatabase.remoteKeysDao().clearRemoteKeys()
movieDatabase.MovieDao().clearMovies()
}
val prevKey = if (page == MOVIES_API_STARTING_PAGE_INDEX) null else page - 1
val nextKey = if (endOfPagination) null else page + 1

val keys = response.map {
RemoteKeys(movieId = it.movieID, prevKey = prevKey, nextKey = nextKey)
}
movieDatabase.remoteKeysDao().insertAll(keys)
movieDatabase.MovieDao().insertMovies(response)
}
return MediatorResult.Success(endOfPaginationReached = endOfPagination)
} catch (ex: Exception) {
return MediatorResult.Error(ex)
}
}

private suspend fun getRemoteKeyForFirstItem(state: PagingState): RemoteKeys? {
// Get the last page that was retrieved, that contained items.
// From that last page, get the last item
return state.pages.firstOrNull() { it.data.isNotEmpty() }?.data?.firstOrNull()
?.let { movieId ->
// Get the remote keys of the last item retrieved
movieDatabase.remoteKeysDao().remoteKeysRepoId(movieId.movieID)
}
}
private suspend fun getRemoteKeyClosestToCurrentPosition(state: PagingState): RemoteKeys? {
// The paging library is trying to load data after the anchor position
// Get the item closest to the anchor position
return state.anchorPosition?.let { position ->
state.closestItemToPosition(position)?.movieID?.let { movieId ->
movieDatabase.remoteKeysDao().remoteKeysRepoId(movieId = movieId)
}
}
}

private suspend fun getRemoteKeyForLastItem(state: PagingState): RemoteKeys? {
// Get the last page that was retrieved, that contained items.
// From that last page, get the last item
return state.pages.lastOrNull() { it.data.isNotEmpty() }?.data?.lastOrNull()
?.let { repo ->
// Get the remote keys of the last item retrieved
movieDatabase.remoteKeysDao().remoteKeysRepoId(movieId = repo.movieID)
}
}

}
  • Передача RemoteMediator в данные подкачки
val dataFlow : kotlinx.coroutines.flow.Flow =
Pager(getPagingConfig(),
remoteMediator = MoviesMediator(authResponse,movieDatabase)){
MoviePagingSource(authResponse)
}.flow
.cachedIn(viewModelScope)

  • Отображение данных в MainActivity
@ExperimentalPagingApi
private fun setUpAdapterOnline(){
moviesAdapter = MoviesAdapter()
lifecycleScope.launchWhenStarted {
moviesModel.dataFlow.collectLatest {
moviesAdapter.submitData(it)
}
}

binding.recycler.adapter = moviesAdapter
binding.recycler.adapter = moviesAdapter.withLoadStateHeaderAndFooter(
header = LoadingStateAdapter { moviesAdapter.retry() },
footer = LoadingStateAdapter { moviesAdapter.retry() }
)
}


Подробнее здесь: https://stackoverflow.com/questions/675 ... m-database
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»