In may project I am using the Paging library from Android Architecture Components. Data is read from the Room db which is used as a cache and when the end of the list is reached I fetch new data from the network api with Boundary callbacks. Unfortunatelly when new updates are called from the api, it is being called 4 or more times, even with boolean flags in the method so the new data is incorrect.
From database I return Datasource.Factory:
@Query("SELECT * FROM movieentity ORDER BY popularity DESC")
fun allMovies(): DataSource.Factory<Int, MovieEntity>
Methods in Repository, basically I want to clear cache and lead next page from the 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())
}
}
The Boundary callback class is defined in ViewModel as innner class:
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()
}
}
For RecyclerView's adapter I extend PagedListAdapter. Maybe the problem is because of coroutines?Please help me solve this problem or give a hint. Thanks in advance.