J'utilise la nouvelle bibliothèque de pagination pour charger des données paginées à partir d'une API restante, mais je n'arrive pas à comprendre comment continuer à charger des données fraîches après leur mise en cache dans Room. Actuellement, j'ai un PagedListAdapter mis à jour à l'aide d'un rappel de limite pour charger des éléments à partir de l'API, qui sont ensuite stockés dans la base de données locale (Room), qui sont émises vers l'interface utilisateur via un flux.
les appels onZeroItemsLoaded et onItemAtEndLoaded à partir de BoundaryCallback fonctionnent tous comme prévu, mais uniquement pour le chargement initial. Une fois que les données ont été extraites une fois et stockées dans le cache (Room), je n’obtiendrai jamais de nouvelles données du service réseau. Le cache contient déjà des données et les rappels de limite ne sont pas déclenchés.
Comment marquez-vous les éléments périmés à l'aide de la bibliothèque de pagination de manière à ce que chaque fois que l'application s'ouvre, mes données sont actualisées?
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)
L’intérêt de cette technique (base de données et reste) est de mettre en cache les données et d’empêcher de les charger à nouveau . Mais si vos données ne sont pas statiques et si elles peuvent être modifiées ou invalidées ... vous pouvez avoir deux approches:
1 - Supprimez tous les enregistrements de la base de données après la fermeture de l'application (ou au démarrage de l'application. Les rappels détruits ne sont pas viables). Dans ce cas, vous obtiendrez de nouvelles données après le prochain démarrage.
2 - Créez un champ dans votre base de données avec la date "Expiration" ou quelque chose de similaire. Continuez à vérifier le champ sur onItemAtFrontLoaded
dans boundaryCallback
s'ils sont expirés, vous pouvez l'invalider et le récupérer à nouveau du service Web.