Rest API Pagination with Paging Library.

Almost every REST API your app call requires to handle pagination. When calling a REST API for resource delivering all of the results could be time-consuming, a REST API will typically make you paginate through the results. If you are trying to support pagination on a client you need to handle it gracefully.

Let’s say that there’s an API endpoint that returns a list of users. In the database of the API, there are 100,000+ users. It would be impractical to fetch all 100,000 users from the API all in one request. In fact, we would probably get an OutOfMemory exception. To avoid this, we want to paginate through our list of the user when making requests to our API.

Paging Library call REST API

 

Paging Library


The new paging library makes it easier for your app to gradually load information as needed from a REST API, without overloading the device or waiting too long for an all result.This library contains several classes to streamline the process of requesting data as you need it. These classes also work seamlessly with existing architecture components, like Room.

1.Adding Components to your Project


Architecture Components are available from Google’s Maven repository. To use them, follow these steps:

Open the build.gradle file for your project and add the line as shown below:

Add Architecture Components

In this tutorial, we are using LiveData, and ViewModel.

Open the build.gradle file for your app or module and add the artifacts that you need as dependencies:

2.Setting up Retrofit for Pagination


The code samples below for making the API calls are using Retrofit with GSON.We are working with the GitHub API and making a call to the GitHub User endpoint.

Now, let’s write our class that will generate our RetrofitService.

3.Create ItemKeyedDataSource


Use ItemKeyedDataSource class to define a data source.It uses for incremental data loading for paging keyed content, where loaded content uses previously loaded items as input to next loads.

Implement a DataSource using ItemKeyedDataSource if you need to use data from item N - 1 to load item N. This is common, for example, in sorted database queries where attributes of the item such just before the next query define how to execute it.

To implement, extend ItemKeyedDataSourcesubclass.

4.DataSourceFactory


A simple data source factory which also provides a way to observe the last created data source.This allows us to channel its network request status etc back to the UI.

5.Create ViewModel


In the ViewModel, we would extend from the Architecture Component ViewModel, and then we would keep a reference to that LiveData of our PagedList.

LivePagedListBuilder:This class generates a LiveData<PagedList> from the DataSource.Factory you provide.
PagedList: A PagedList is a List which loads its data in chunks (pages) from a DataSource.All data in a PagedList is loaded from its DataSource. Creating a PagedList loads data from the DataSource immediately, and should, for this reason, be done on a background thread. The constructed PagedList may then be passed to and used on the UI thread. This is done to prevent passing a list with no loaded content to the UI thread, which should generally not be presented to the user.

6.Create ProgressBar as Footer in a RecyclerView


Create RecyclerView with 2 type of items one is our usual items the second is a progress bar, then we need to listen NetworkState LiveData and decide are we going to show ProgressBar or not.

network_state_item.xml

Now, set the Network State and add or remove ProgressBar in Adapter.

hasExtraRow() check the Network State and return true or false.

To tell the PagedListAdapter how to compute the difference between the two elements, you’ll need to implement a new class, DiffCallback.Here, you will define two things.

You will define how to compute whether the contents are the same, and how to define whether the items are the same.
Let’s look at the adapter.So our adapter would extend PagedListAdapter, and then it will connect the user, which is the information that’s being displayed, with the user ViewHolder.

We define the callback, the DIFF_CALLBACK, for our user objects and then in onBindViewHolder, all we need to do is bind the item to the ViewHolder.

7.Create RecyclerView


In the onCreate, we get the reference to our ViewModel and get the reference to the RecyclerView, and we create our adapter.

 

Download this project from GitHub

 

Related Post

Architecture Components: Paging Library.

 

 

Architecture Components:Paging Library

Database queries take a long time to run and use a lot of memory. Android has a new paging library that can help you with all of this.

Main Classes of Paging Library


The main classes of the paging library are PagedListAdapter, that actually extends the RecyclerViewAdapter, PagedList, and DataSource.

DataSource: The DataSource is an interface for page source to provide the data gradually.

If you use the Room persistence library to manage your data, it can generate a DataSource.Factory to producePositionalDataSources for you automatically, for example:

PagedList: The PagedList is a component that loads the data automatically and can provide update signal, for example, to the RecyclerViewAdapter. The data is loaded automatically from a DataSource on the background thread.But then, it’s consumed on the main thread.It supports both an infinite scrolling list, but also countable lists.

You can configure several things.You can configure the initial load size, the page size, but also the prefetch distance.

PagedListAdapter:This class is an implementation of RecyclerView.Adapter that presents data from a PagedList. For example, when a new page is loaded, the PagedListAdapter signals the RecyclerView that the data has arrived; this lets the RecyclerView replace any placeholders with the actual items, performing the appropriate animation.

The PagedListAdapter also uses a background thread to compute changes from one PagedList to the next for example, when a database change produces a new PagedList with updated data, and calls the notifyItem…()methods as needed to update the list’s contents. RecyclerView then performs the necessary changes. For example, if an item changes position between PagedList versions, the RecyclerView animates that item moving to the new location in the list.

DataFlow


We have some data that we put on the DataSource in the background thread.The DataSource invalidates the PagedList and +updates its value.

Then on the main thread, the PagedList notifies its observers of the new value.Now the PagedListAdapter knows about the new value.

The background thread, the PageListAdapter needs to compute what’s changed, whats’ the difference and back on the UI thread, the View is updated in the onBinderViewHolder.

So all of this happens automatically.You just insert an item in that database, and then you see it animated in and no UI code is required.

Paging Library Example

Architecture Components Paging Demo

1.Adding Components to your Project


Architecture Components are available from Google’s Maven repository. To use them, follow these steps:

Open the build.gradle file for your project and add the line as shown below:

Add Architecture Components

In this tutorial, we are using Room, LiveData, and ViewModel.

Open the build.gradle file for your app or module and add the artifacts that you need as dependencies:

2.Create DataSource


Create Entity

Represents a class that holds a database row. For each entity, a database table is created to hold the items. You must reference the entity class in the Database class.

Data Access Objects (DAO)

To simplify the connection between the DataSource and the RecyclerView, we can use a LivePagedListProvider.So this will expose, actually, a LiveData of a PageList of our user.So all you will need to do is provide a DataSource.But if that DataSource is true, then it will be generated for you in the DAO.You don’t need to write any invalidating handling code.You can simply bind the LiveData of a PagedList to a PagedListAdapter and get updates, invalidates, and lifecycle cleanup with a single line of binding code.

So in our user DAO, we would return a LivePagedListProvider of our user to get the users by the last name.

Create Database

The annotation defines the list of entities, and the class’s content defines the list of data access objects (DAOs) in the database. It is also the main access point for the underlying connection.

The annotated class should be an abstract class that extends RoomDatabase.

3.Create ViewModel


In the ViewModel, we would extend from the Architecture Component ViewModel, and then we would keep a reference to that LiveData of our PagedList and we will get that reference from the DAO by calling getUsers(), and then call Create using the configuration that you want.So for example, setting the page size to 50, setting the prefetch distance to 50 and so on.

In the onCreate, we get the reference to our ViewModel.We get the reference to the RecyclerView, and we create our adapter.

4.Create Adapter


To tell the PagedListAdapter how to compute the difference between the two elements, you’ll need to implement a new class, DiffCallback.Here, you will define two things.

You will define how to compute whether the contents are the same, and how to define whether the items are the same.

Let’s look at the adapter.So our adapter would extend PagedListAdapter, and then it will connect the user, which is the information that’s being displayed, with the user ViewHolder.

We define the callback, the DIFF_CALLBACK, for our user objects and then in onBindViewHolder, all we need to do is bind the item to the ViewHolder.That’s all.

 

Download this project from GitHub

 

Related Post

Rest API Pagination with Paging Library.

 

Room: Database Relationships

Most modern applications today use databases for offline storage. This interaction is very easy using Room Persistence Library.In this tutorial, we’ll learn how to work with multiple tables that have relationships with each other. First, we will go over some core concepts, and then will begin working with JOIN queries in SQL.

There are several types of database relationships. Today we are going to cover the following:

  • One to One Relationships
  • One to Many and Many to One Relationships
  • Many to Many Relationships

When selecting data from multiple tables with relationships, we will be using the JOIN query.

Room: One-To-One Relationships


In this example you will learn how to map one-to-one relationship using Room. Consider the following relationship between Customer and Address entity.
Room: One-To-One mappingTo create this relationship you need to have a CUSTOMER and ADDRESS table. The relational model is shown below.

Room: One-To-One mapping

Use a primary key

Each entity must define at least 1 field as a primary key. Even when there is only 1 field, you still need to annotate the field with the @PrimaryKey annotation. Also, if you want Room to assign automatic IDs to entities, you can set the @PrimaryKey‘s autoGenerate property.

Define relationships between objects

You need to specify relationships between customer and address objects. The Room allows you to define Foreign Key constraints between entities.

For example, if there’s Customer entity, you can define its relationship to the Address entity using the @ForeignKeyannotation, as shown in the following code snippet.

Now we have a relationship between the Customers table and the Addresses table. If each address can belong to only one customer, this relationship is “One to One”. Keep in mind that this kind of relationship is not very common.

Our initial table that included the address along with the customer could have worked fine in most cases.Notice that now there is a field named “address_id” in the Customers table, that refers to the matching record in the Address table.

Room: One-To-Many Relationships


This is the most commonly used type of relationship. Consider an e-commerce app, with the following:

  • Customers can make many orders
  • Orders can contain many items
  • Items can have descriptions in many languages

In these cases, we would need to create “One to Many” relationships. Here is an example:
In the following example, you will learn how to map one-to-many relationship using Room. Consider the following relationship between Customer and Order entity.
Room: One-To-ManyAccording to the relationship, a Customer can have any number of Orders.
To create this relationship you need to have a Customer and Order table. The relational model is shown below.
Room: One-To-Many

Each customer may have zero, one or multiple orders. But an order can belong to only one customer.

To create Order table you need to create the following Java bean class.

Room: Many to Many Relationships


In some cases, you may need multiple instances on both sides of the relationship. For example, each order can contain multiple items. And each item can also be in multiple orders.

Room: Many to Many RelationshipsFor these relationships, we need to create an extra table:
Room: Many to Many Relationships
The item_order table has only one purpose, and that is to create a “Many to Many” relationship between the items and the orders.

To create the items and item_order tables you need to create the following Java Bean class.

Annotate indices and uniqueness

Sometimes, certain fields or groups of fields in a database must be unique. You can enforce this uniqueness property by setting the unique property of an @Index annotation to true. The following code sample prevents a table from having two rows that contain the same set of values for the order_id and item_id columns:

Join Queries


Some of your queries might require join tables to calculate the result. Room allows you to write any query. Furthermore, if the response is an observable data type, such as Flowable or LiveData, Room watches all tables referenced in the query for invalidation.

The following code snippet shows how to perform a table join to consolidate information between a table.

 

Related Post

Room Persistence Library

How to use DateTime datatype in SQLite Using Room

Room database Migrating

 

Room Persistence Library

In the database the best practice to put your database access into certain interfaces.We want to get rid of the SQLite boilerplate free code.Room Write boilerplate code for you.You define the interfaces Room provide the implementation.

Compile time validation


The room is going to give you an error at compile time.So it goes out and verifies your query against the schema you have defined.

Data Changes


LiveData gets notified when the data changes.Because it Knows your query, it knows what things affect it.So it can let you know if that query changes.

This is the part where all these architecture components work well together.

Your ViewModel all you would write is the data, from the data is call this query and this all it will do.Whenever that data changes, your UI will get a new update.

Adding Components to your Project


open the build.gradle file of  project  and add the line as shown below:

Open the build.gradle file for your app and add the artifacts that you need as dependencies:

Create Entity


Represents a class that holds a database row. For each entity, a database table is created to hold the items. You must reference the entity class in the Database class. Each field of the entity is persisted in the database unless you annotate it with @Ignore.

room entity

When a class is annotated with @Entity and is referenced in the entities property of a @Database annotation, Room creates a database table for that entity in the database.

Nested objects


You’d like to express a POJO as a cohesive whole in your database logic.In these situations, you can use the @Embedded annotation to represent an object that you’d like to decompose into its subfields within a table. You can then query the embedded fields just as you would for other individual columns.

Our User class can include a field of type Address. To store the composed columns separately in the table, include an Address field in the User class that is annotated with @Embedded, as shown in the following code snippet:

Indices and uniqueness


Index certain fields in the database to speed up your queries. To add indices to an entity, include the indices property within the @Entity annotation.You can enforce this uniqueness property by setting the uniqueproperty of an @Index annotation to true.

Relationships


Room allows you to define Foreign Key constraints between entities.

For example, if there’s another entity called Book, you can define its relationship to the User entity using the @ForeignKey annotation, as shown in the following code snippet:

You can tell SQLite to delete all books for a user if the corresponding instance of User is deleted by including onDelete=CASCADE in the @ForeignKey annotation.

Data Access Objects (DAO)


This component represents a class or interface as a Data Access Object (DAO). DAO are responsible for defining the methods that access the database. When generating the code at compile time, Room creates an implementation of this class.

@Insert

Create a DAO method annotate with @Insert .Room generates an implementation that inserts all parameters into the database in a single transaction.

The following code snippet shows example queries:

It can return a long, which is the new rowId for the inserted item. If the parameter is an array or a collection, it should return long[] or List<Long> .

@Update

It uses a query that matches against the primary key of each entity.

@Delete

Deletes a set of entities, given as parameters, from the database. It uses the primary keys to find the entities to delete.

Delete and Update method can return an int value instead, indicating the number of rows updated in the database.

@Query

It allows you to perform read/write operations on a database. Each @Query method is verified at compile time.

The room also verifies the return value of the query such that if the name of the field in the returned object doesn’t match the corresponding column names in the query response.

Querying multiple tables(JOIN)

The room allows you to write join tables. Furthermore, if the response is an observable data type, such as Flowable or LiveData, Room watches all tables referenced in the query for invalidation.

The following code snippet shows how to perform a table join to consolidate information between a table containing users who are borrowing books.

Data type converters


You sometimes use a custom data type whose value you would like to store in the database in a single column. To add this kind of support for custom types, you provide a TypeConverter, which converts a custom class to and from a known type that Room can persist.

Create Database


The annotation defines the list of entities, and the class’s content defines the list of data access objects (DAOs) in the database. It is also the main access point for the underlying connection.

The annotated class should be an abstract class that extends RoomDatabase.

The class must contain an abstract method that has zero arguments and returns the class that is annotated with @Dao.

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long periods of time.

At runtime, you can acquire an instance of it by calling Room.databaseBuilder() or Room.inMemoryDatabaseBuilder().

Download this project from GitHub.

 

Related Post

Room: Database Relationships

Room database Migrating