I'm utilizing the new Paging library to load paginated data from a rest API, but I'm having trouble understanding how to continue loading fresh data after it's cached in Room. Currently, I have a PagedListAdapter that's updated by using a boundary callback to load items from API, which are then stored in the local DB (Room), which are emitted to the UI via a flowable.
onZeroItemsLoaded and onItemAtEndLoaded calls from the BoundaryCallback are all functioning as expected, but only for the initial load. Once the data is retrieved once and stored in cache (Room), I'll never get fresh data from the network service--there's already data in the cache and the boundary callbacks are not triggered.
How do you mark items stale using the paging library so that every time the app opens my data is fresh?
ItemCallback.kt:
class ItemBoundaryCallback : PagedList.BoundaryCallback<Item>() {
override fun onZeroItemsLoaded() {
itemsFromNetwork(0)
}
override fun onItemAtEndLoaded(itemAtEnd: Item) {
itemsFromNetwork(itemAtEnd.rank)
}
}
ItemRepository.kt:
fun items(): Flowable<PagedList<Item>> {
return RxPagedListBuilder(database.itemDao().items(), pageSize)
.setBoundaryCallback(boundaryCallback)
.buildFlowable(BackpressureStrategy.LATEST)
}
ItemDao.kt
@Query("SELECT * FROM item ORDER BY rank ASC")
fun items(): DataSource.Factory<Int, Item>
ItemAdapter.kt
class ItemAdapter() : PagedListAdapter<Item, ItemViewHolder>(diffCallback) {
companion object {
private val diffCallback = object : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(old: Item, new: Item): Boolean = old.id == new.id
override fun areContentsTheSame(old: Item, new: Item): Boolean = old == new
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
return ItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.r_item, parent, false))
}
override fun onBindViewHolder(viewHolder: ItemViewHolder, position: Int) {
viewHolder.bind(getItem(position), clickListener)
}
}
ItemFragment.kt
override fun onStart() {
super.onStart()
itemRepository.items()
.subscribe(itemAdapter::submitList)
.addTo(disposables)
A click on the like button should refresh the item.
The Paging library helps you load and display pages of data from a larger dataset from local storage or over network. This approach allows your app to use both network bandwidth and system resources more efficiently.
The whole point of using this technique ( database and rest) is caching data and preventing to load them again. But if your data is not static and it may be changed or invalidated. you can have two approaches:
1 - Remove every record in the database after closing the app (or when starting the app. destroy callbacks are not viable), in this case, you will get fresh data after next start.
2 - Make a field in your database as "Expiration" date or something similar. keep checking the field on onItemAtFrontLoaded
in boundaryCallback
if they're expired you can invalidate and fetch it again from web service.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With