Enter the Paging Library
The Paging library exists to provide greater developer control over exactly what gets loaded from a backing data store and when, handling things like:
- Performing smaller queries, to stay inside a
CursorWindow
’s bounds, so we can control the threads used for data loads - Supporting multiple traversal options through a data set: not only classic position-based systems, but ones where you might be navigating a tree and need to retrieve related child objects as part of traversal
- Offering reactive approaches, based on
LiveData
, so we can ensure that our UI remains responsive.
There are a number of classes involved in the Paging library, but for basic scenarios, there are a few of significance: including PagedList
and PagedListAdapter
.
PagedList
PagedList
, on the surface, is a List
, not that dissimilar from an ArrayList
. However, it is designed to handle very large collections using a time-honored technique: lying.
A PagedList
may know how much data there can be — to be able to respond to methods like size()
— but it does not actually hold all of that data. Instead, it holds onto a small amount of data and by default will return null
for requests to get items from the List
that have not been loaded.
A loadAround()
method tells the PagedList
a position of importance. Asynchronously, PagedList
will work to load that data and be able to return non-null
values for positions “around” the requested one. This may cause the PagedList
to jettison previously-loaded data, to minimize the memory footprint that the PagedList
takes up.
The idea is that PagedList
should work the way that the UI does: showing a small amount of information at a time, but allowing for (theoretically) arbitrary navigation through a much larger set of information.
PagedListAdapter
A PagedListAdapter
is a RecyclerView.Adapter
that uses a PagedList
as its source of items to render. It handles the details of calling loadAround()
for you. All you need to do is handle standard RecyclerView.Adapter
methods like onCreateViewHolder()
and onBindViewHolder()
.
DataSource.Factory
A DataSource
, surprisingly enough, is a source of data. It is a wrapper around some data provider — a database, a Web service, etc. — and knows how to retrieve pages of data from it.
A DataSource.Factory
follows a time-honored Java tradition, where we have factory classes to create instances of other things. In this case, a DataSource.Factory
knows how to create certain types of DataSource
. In particular, when working with Room, you can request that a @Query
method return a DataSource.Factory
as its data type, instead of a List
of entities or a LiveData
or other things.
LivePagedListProvider
LivePagedListProvider
is a utility class that can create a LiveData
object that delivers PagedList
objects to observers, given a DataSource.Factory
. So, if you have a Room @Query
method that returns a DataSource.Factory
, you can create a LivePagedListProvider
to convert that into a LiveData
for use with your UI layer. Room, DataSource.Factory
, and PagedList
will handle loading data asynchronously as you navigate through the list. If you attach the PagedList
to a RecyclerView
via PagedListAdapter
, you get seamless data paging, with controllable memory consumption, with very little work on your part.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.