В майском проекте я использую библиотеку подкачки из компонентов архитектуры Android. Данные считываются из Room db, которая используется в качестве кеша, и когда достигается конец списка, я получаю новые данные из сетевого API с помощью обратных вызовов Boundary. К сожалению, когда новые обновления вызываются из API, он вызывается 4 или более раз, даже с логическими флагами в методе, поэтому новые данные неверны.
Из базы данных я возвращаю Datasource.Factory:
@Query("SELECT * FROM movieentity ORDER BY popularity DESC")
fun allMovies(): DataSource.Factory<Int, MovieEntity>
Методы в репозитории, в основном я хочу очистить кеш и перейти на следующую страницу из API:
override fun allMovies(movieBoundaryCallback:
MainViewModel.MovieBoundaryCallback): LiveData<PagedList<Movie>> {
// Get data source factory from the local cache
val dataSourceFactory = moviesDao.allMovies().map {
MovieMapper.fromDb(
it
)
}
val config: PagedList.Config = PagedList.Config.Builder()
.setInitialLoadSizeHint(DATABASE_PAGE_SIZE)
.setPageSize(DATABASE_PAGE_SIZE)
.setPrefetchDistance(0)
.build()
// Get the paged list
return LivePagedListBuilder(dataSourceFactory, config)
.setBoundaryCallback(movieBoundaryCallback)
.build()
}
override suspend fun refreshMovies(page: Int) {
withContext(Dispatchers.IO) {
moviesDao.deleteAll()
moviesDao.insertAll(*fetchMovies(page).toTypedArray())
}
}
Класс обратного вызова Boundary определен в ViewModel как внутренний класс:
val callback = MovieBoundaryCallback()
// get movies saved in local db
val movies = getMoviesUseCase.allMovies(callback)
...
inner class MovieBoundaryCallback : PagedList.BoundaryCallback<Movie>() {
private var lastRequestedPage = 1
private var isRequestInProgress = false
private fun refreshMoviesList() {
if (isRequestInProgress) return
isRequestInProgress = true
if (isInternetAvailable(getApplication())) {
lastRequestedPage++
try {
viewModelScope.launch {
getMoviesUseCase.refreshMovies(lastRequestedPage)
}
isRequestInProgress = false
} catch (e: Exception) {
e.printStackTrace()
}
}
}
override fun onItemAtEndLoaded(itemAtEnd: Movie) {
refreshMoviesList()
}
}
Для адаптера RecyclerView я расширяю PagedListAdapter. Может быть проблема в сопрограммах? Пожалуйста, помогите мне решить эту проблему или дайте подсказку. Заранее спасибо.