Arm*_*186 5 android coroutine kotlin android-paging
在 May 项目中,我使用了 Android Architecture Components 中的 Paging 库。从用作缓存的 Room db 读取数据,当到达列表末尾时,我使用 Boundary 回调从网络 api 获取新数据。不幸的是,当从 api 调用新的更新时,它会被调用 4 次或更多次,即使方法中有布尔标志,因此新数据是不正确的。
从数据库我返回 Datasource.Factory:
@Query("SELECT * FROM movieentity ORDER BY popularity DESC")
fun allMovies(): DataSource.Factory<Int, MovieEntity>
Run Code Online (Sandbox Code Playgroud)
Repository中的方法,基本上我想从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())
}
}
Run Code Online (Sandbox Code Playgroud)
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()
}
}
Run Code Online (Sandbox Code Playgroud)
对于 RecyclerView 的适配器,我扩展了 PagedListAdapter。也许问题是因为协程?请帮我解决这个问题或给一个提示。提前致谢。
我不太确定,但我猜问题是因为deleteAll() insertAll()。Room 数据库的优点之一是它们是反应性的,这样它们就可以在数据修改时发布信息,这是一个非常酷的功能。
问题是,有时他们太反应了。deleteAll() insertAll() 始终是 Room DB 的问题,因为 DB 在 deleteAll() 之后以及 insertAll() 之后发送数据。您必须使您的 WS 适应分页数据库,以便能够仅检索所需的数据,并且在现有实体可能发生更改的情况下,能够执行“智能 insertAll()”...
归档时间: |
|
查看次数: |
1195 次 |
最近记录: |