Rest API Pagination with Paging Library.

Almost every REST API your app call requires to handle pagination. When calling an REST API for some resource instead of delivering all of the results, which could be time-consuming and cumbersome to deal with, 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.

Rest Api Pagination with Paging Library

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 TiledDataSource


UseTiledDataSource class to define a data source.It uses for incremental data loading, used in list paging. You can load arbitrary pages based solely on the position information and can provide a fixed item count. TiledDataSource supports querying pages at arbitrary positions, so can provide data to PagedLists in arbitrary order.

To implement, extend TiledDataSourcesubclass.

4.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.

LivePagedListProvider: It is use for construct Database that return LiveData.
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.

5.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.

6.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

 

Related Post

Architecture Components:Paging Library.

 

 

Architecture Components:Paging Library

Many Applications need to load a lot of information from the database.Database queries can 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 Components of Paging Library


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

Component Of Paging Library

DataSource: The DataSource is an interface for page source to provide the data gradually.But you’ll need to implement one of the two DataSource, either a Keyed DataSource or TiledDataSource, which will be used when you need to load item N based on the item N-1.

  • Use KeyedDataSource if you need to use data from item N to fetch item N+1. For example, if you’re fetching threaded comments for a discussion app, you might need to pass the ID of one comment to get the contents of the next comment.
  • Use TiledDataSource if you need to fetch pages of data from any location you choose in your data store. This class supports requesting a set of data items beginning from whatever location you select, like “Return the 20 data items beginning with location 1200”.
  • loadCount():You also need to implement another method,loadCount()This tells whether you have an infinite or finite amount of items that you need to display in your list.

If you use the Room persistence library to manage your data, it can create the DataSource class for you automatically. For example, here’s a query that returns a TiledDataSource:

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


Paging data flow

Let’s say that we have some data that we put on the DataSource on 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.So now the PagedListAdapter knows about the new value.So on the background thread, the PageListAdapter needs to compute what’s changed, whats’ the difference.Then, 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


Live Paged List Provider

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

Conclusion

Android has a lot of new concepts and components with architecture Components.But the thing is, you can them separately.So if you want, you’ll only be able to use lifecycle, LiveData, and PagedList or only ViewModel, or only Room.But you can also use them together.So start using the Architecture Components to create a more testable architecture for your application.

 

Related Post

Rest API Pagination with Paging Library.

 

Fragment Tricks

  There’s a lot of information out on the web as people have used the API gotten kind of familiar with it and in some ways kind of got bitten by it.There’s a lot of complexity there.

Why use fragment at all?

If we want to group UI components, couldn’t we just create a ViewGroup or maybe a re-usable XML layout definition? Yes but the real power in fragments goes beyond grouping UI elements.They allow us to fully modularize our activity, including the lifecycle events they receive in the app state that they maintain.Treat each fragment as though it were a mini activity.

Breaking your app into different activities. Having a single monolithic activity increases the complexity of your code.

Making the creation and management of intent filters much harder and making it more difficult to maintain, test, and read your activity code. It also increases the risk of tightly coupling independent components and makes it much more likely to introduce security risks if the single activity includes both sensitive information and information that’s safe to share.

When to use Activity?

A good rule of thumb is to create a new activity whenever the context changes.For example, displaying a different kind of data while switching from viewing to entering data.

Single Activity Architecture

With a single activity architecture, you simply have one activity and you have your view for your screen number A at number A. and instead of having a new activity for your screen B, you simply swap the view.

Fragment lifecycle 

The basic lifecycle events are much the same as the parent activity.It moves through the cycle of starts, resumes, pauses and stops those same lifecycle events will be triggered within the fragment itself.In most cases, you can simply move anything that you would have put into the activity lifecycle handles into the corresponding fragment handlers.

Fragment Lifecycel

 

onCreateView : Fragment introduced a new event specifically for UI.Here, You construct or inflate your UI, hook up to any data sources, and return it you the parent activity which can then integrate it into its view hierarchy.

There’s a correspond onDestroyView handler, which is called immediately before the fragment is added to the back stack, independent of the parent activity, onDestroyView is where you should clean up any resources specifically related to the UI, such as bitmaps in memory, cursors to data, anything like that to help ensure that your app’s memory footprint isn’t bloated by data that’s not needed  when the fragment isn’t visible.

Now as soon as the fragment is returned from the back stack,onCreateView is call and you can re-create the UI and reconnect data sources before your fragment transitions through the rest of the lifecycle to become active again.And because a fragment can only exist within an activity.

We also need callbacks to tell us when a fragment is attached and detached from its parent.OnAttach is your opportunity to get a reference to the parent activity.While onDetach is the last thing that happens,

onActivityCreated This notifies our fragment that the parent activity has completed it’s onCreate handler

Fragment Tricks

I am going to be writing about a few effective patterns for using the fragment API in your apps.Some of these are going to be they may seem a little bit basic, but they’re also things that are going to help you build apps in a way that factors your code effectively, encapsulates things and, makes sure that you can keep your code clean.

Where is fragment API came from?

As Android started moving into large screen devices in honeycomb, It is realizing that there are a few specific patterns in the way that some apps are put together, especially apps of the time.You’ve got one area that’s devoted to your navigation, and you got another area that’s devoted to content.When you put these two things together, you can imagine on a small screen device you might see the navigation as on screen that advances to the content screen, and when you’re on a larger screen device you’re able to show the same thing side by side.

It was something that you could use to factor out your activity components into two separate pieces that you could show differently based on different device configurations.Now this works really well for some application like Gmail, but your app probably isn’t Gmail.If you followed the development of app design.This sort of pattern just doesn’t fit for a lot of things.

However, it’s still extremely useful for representing your application as a series of destinations.So even on a small screen device, you might have an app that looks something like this.

Fragment Transition animation

Download this project from GitHub.

We’ve got our little application that–where you can order some flowers.For each one of these screens, you can perform a replace transaction to replace the destination that you were looking at previously with the new one.Replace transaction will remove any fragment in the container and then add new fragment. So the nice thing about is that you can place these particular transaction on the back stack, and we’ll go ahead and handle that back navigation for you

Now the nice thing about this is that the content and navigation pane separation isn’t limited to just large screens. This can really help to keep your chrome stable.

In your application you have things like bars,net drawers,bottom navigation bars, any of these things that you want to keep stable and perform some consistent animations from one screen to another this really lets you do it in a way that is really difficult to accomplish with the activity  to activity transitions where you can’t preserve that kind of continuity in your UI as you navigate deeper in your app’s hierarchy.

Navigation Flows

I’m talking about those step-by-step flows that you have in your application.So when you have a checkout or a sign up or a setup wizard, the users are going to go step by step through their navigation, and then they might want to wander back using the back button and then go forward again and then when they’re all done, you want to be all done with that.You don’t want that one user to be able to go back through the checkout process again

Key to back stack management

1.Do maintain the back stack as you navigation forward(It’s so much easier to manage your back stack if you choose the direction your user is going to go on the back stack as you navigation forward).

2.Don’t , at the time the user press the back button, choose what they’re going to do.That’s a lot harder to manage. So to take advantage of this kind of thing, sometimes you need to do some synthetic back stack management that means if you have an external link into your application, some kind of deep, nested thing, they’re selecting a particular cart item.When they hit the back button, you don’t want them to go to some–the main screen, you want them to go into the category, perhaps DON’T decide on back button navigation behavior just-in-time.

Repeated commits start and stop each fragment.

If you make repeated transactions, then that means that each one of that transaction you’re going to start and stop those fragments as you execute each one in turn.So that can be really expensive right?

how do you can go ahead and maintain that back stack state?

While still not doing a whole lot of really heavyweight work as you start and stop each one of those fragments along the way? Because you have to create all those views, tear them down again, inflation.It seems like a lot of unnecessary work.

setReorderingAllowed(true) :It allows all of the execution to happen all at once without changing your fragment state. And then at the very end, we bring up all the fragments that need to be brought up and tear down all the fragments that need be torn down.and now you’re fragments don’t have to go through all that.

 

ViewGroup or Fragment?

Using a custom ViewGroup or a Fragment in these case, Is does it implement mechanism or does it implement policy? Is it an isolated widget that generates its own input events?(Is it an isolated widget, or does it connect app logic?)

Views should really only be responsible for displaying information and publishing direct user interaction events.These end up being very low level events, like button was clicked user scrolled something.

These are responsible for drawing text and these other sorts of operations that are user interaction, wheres fragments integrate with the surrounding lifecycle and they may be aware of the app components.

Fragment is really what gives context to everything  that you’re doing in your UI.(Bind to a service, communicate with your app’s data model performing a database query, so on and so forth)

So you should never use a Fragment when a View will do, but you also want make sure that you’re not adding outside dependencies to your Views. It’s definitely a code smell if you ever find yourself doing something like trying

To bind a service from a view implementation, or trying to make a network call or again, trying to integrate with anything that’s outside of the realm of just that one individual view.

But that means that there’s a whole.It means that you can’t building just something that simple as completely self-contained like button

Don’t use a Fragment when just a composite custom ViewGroup, or even just a layout resource that you can use an include tag, wild the job better.

LiveData

It’s very common that your activity or fragment observe some data, and whenever that data changes, It wants to refresh itself.It’s like your activity receives a callback, but the activity already stopped.If an activity or a fragment is stopped there is no reason to update that UI.If the activity happens to become visible again then you want to do it.

We want to share resources across multiple fragments or activities.For example, the Location of the device is the same from fragment to fragment.If you have two fragments, why do you need to create two listeners to listen to the same location?

Hence, Android create this new LiveData clause.

LiveData

LiveData is a data holder, it just holds some data.It’s like an observable but the tricky thing about it is LifeCycle aware.If you are observing a LiveData, you don’t need to unsubscribe, the right things will happen at the right times.

  • It is a Lifecycle aware Observable.
  • It is very simple to start and stop semantic.(Doesn’t matter how many observers you have or what state they are we merge all of it into one lifecycle).
  • It doesn’t have any activity or fragments inside it works with both of them. It is also really used to test LiveData because it’s’ kind os android free.
  • Android guarantee that your observable will never, ever be called in a state where you cannot run a FragmentTransaction.
  • This is very very specifically designed to work well with your Activity and Fragments.

 

How LiveData Work?

So onCreate, it called to observe, it said LiveData is observable.And as soon as the activity starts it starts receiving data changes. So whenever the LiveData value changes, android displace that event back to your observer inside the activity.

LiveData Rotate screen

On Activity Rotated.So you know that the activity will be stopped.and what happens at the same time, the LiveData happens to be updated.If that happens LiveData is not going to tell the activity about this change. Similarly, if the activity is destroyed, Android will automatically remove the subscription because that activity is gone.

Now, The activity was rotating, so you know that android is going to recreate that activity.and then we are observing the same LiveData back. As soon as the activity starts, it’s going to receive last available data.So your UI is going to have the Data before it gets a chance to draw.

LiveData onStop

If the user hits the Home button which means the activity will be stopped. Again if the LiveData changes while the activity is stopped, is not going to receive any events. Even if the data changes we are not going to tell it.

LiveData reopen app

But as soon as if the user comes back to the application, android will give it the last available data.

So this is why we call LiveData is not just a stream of events.It holds on to data so that if any observer comes, it receive the last available value. and the eventually, the user backs out of that activity, and then we remove that subscription.

LiveData Example

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

Add the Google Maven repository

To add it to your project, open the build.gradle file for your project and add the highlighted line as shown below:

Adding Components to your Project

The activity updates the UI when the new number generated.

LiveData Example

 

LifecycleOwner

MainActivity is an instance of LifecycleActivity, which can provide the state of a lifecycle. This is the class declaration:

To expose data as an observable, wrap the type in a LiveData class.LiveData is a special observable class which is lifecycle-aware, and only notifies active observers.

Add the following code to the MainActivity class, to create the subscription:

Sets the value. If there are active observers, the value will be dispatched to them.

This method must be called from the main thread. If you need set a value from a background thread, you can use postValue(Object).

RxJava vs LiveData

Key different between RxJava and LiveData.LiveData is a holder and not a stream.So we have a reference to the last value, and observer immediately receives the last value when they start to observe liveData.

And now the big different is a threading model.As you know Rxjava has a very sophisticated threading model.It’s extremely powerful but in most cases, you probably don’t need it.LiveData has everything on the main thread.

LiveData is Lifecycle aware.It knows about android life cycles, and when you want to observe a LiveData, you can pass in this LifeCycle so that it manage your subscription.The nice thing about LiveData that is that your observer, and that’s all you do. You don’t need to write onStart, onStop.

You initialize thing as more like find and forget.You initialize and you’re done.

It’s mush easier.As many of you may know the learning curve of Rxjava is super steep.It is simpler, it ‘s faster it’s lightweight, It’s well integrated with a framework.If you feel like you love reacting programming a lot, You want to bring it not only to the relation between UI and the state. You want to bring it to the business part of your application.Then you may consider the addition of RxJava, because it gives you more power.Android will actually help you to do that.Android has this extension to the library, Which gives a possibility to create LiveData from Publisher and create Publisher from LiveData.So this Integration should be quite smooth.

What is an active observer?

You can also extend the LiveData class.Because LiveData provides two really handy callbacks.

We define an active observer as an observer that’s in the STARTED or RESUMED state which is like an activity user is currently seeing.So if you have an observer in the back stack, there’s no reason to put this inactive.There’s no reason to update that activity because the user will never, ever see what’s going on there.

So inside our connect method all we need to do is whenever the system Location Manager sends us a new location we call setValue on ourselves.Then the LiveData knows which are the activity observers, and delivers the data to those observers.if one of the Observer was on the back stack and then becomes visible again, LiveData takes care of sending the latest data back to that observer.

onInactive(), Which means you don’t have any observers, So don’t bother changing your value if it is something that you care about.

 

Related Post

Lifecycle Aware Components

ViewModel

Room Persistence Library

Fragment Tricks

ConstraintLayout 1.1.x

Room Persistence Library

Room Persistence Library

We know that to write a good responsive android app, you need to save data on disk.You need to use SQLite if you want to save big data.We want to get rid of SQLite boilerplate free code.

Room Write boilerplate code for you

Usually, In the database the best practice to put your database access into certain interfaces.You define the interfaces Room provide the implementation.

Full SQLite support

Room Speaks SQL.Most important part of Room is it understands your SQL.So, the Part all those constants. Room actually gives all of this for free.

Compile time validation

Room defined to get compile-time guarantees.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, it tells you is something is wrong.

Incentivises best practices

You can basically create any java class.It doesn’t need to be annotated, there’s nothing special about POJO, and tell Room to return It.As long as whatever query it returns.Matches what you want it to return, Room will write the code for you.

Observability is important ?

We want to get notified when the data changes.If you want to do this all you have to do tell it to return a LiveData and it will do it for you.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.Room already knows about live data.

So 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

You might want to 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.

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)

Room allows you to write any query, so you can also 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.

class must contain an abstract method that has 0 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

How to use DateTime datatype in SQLite Using Room

Lifecycle Aware Components

ViewModel

LiveData

Fragment Tricks

ConstraintLayout 1.1.x

ViewModel

Handling Configuration Changes

If we have an activity where we show a user profile and we implemented a web service that can return that data as a LiveData, Which we can safely observe without risking leaking over activity, What happens if the user rotates to the device?

But then the new activity starts, which make a new call.This is OK but not great, We want to retain that data, so the data it holds is immediately available to the next activity or fragment instance. We are already making that request why remake it?

View Model

ViewModel

Lightweight ViewModel which is all of our effort to take out that code outside of your activities and fragments, and put it somewhere else where you can easily test it.The ViewModel class is designed to store and manage UI-related data so that the data survives configuration changes such as screen rotations.

We create this new class it extend the ViewModel class.Whatever data we had inside the activity, we move it into ViewModel class.   

The very first time you make this call, ViewModel will give you a new Instance.When the rotated activity come back, It’s going reconnect to same ViewModel.

ViewModel is the one which prepares the data for the UI and holds on it.This where the data for the UI lives.ViewModel know how to get that data Usually, it has LiveData.It survives configuration changes.

ViewModel

That’s why we put the data into the ViewModel, and it is also the gateway.You can also consider it as your UI controller only ever talks to the ViewModel to reach to the rest of the application.The ViewModel serves as a data store for UI controller.

ViewModel example

The example uses the Architecture components, Retrofit and the Github API. Requires Android Studio 3.0.

Android ViewModel

Adding ViewModel to your Project

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

Add the Google Maven repository

To add it to your project, open the build.gradle file for your project and add the highlighted line as shown below:

Add Architecture Components

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

 

For the example we’ve mentioned above, it would be the ViewModel’s responsibility to acquire and keep the list of users, not the activity or the fragment.ViewModel’s only responsibility is to manage the data for the UI. It should never access your view hierarchy or hold a reference back to the Activity or the Fragment.

It should never reference a View or any class that may hold a reference to the activity context. If the ViewModel needs the Application context, it can extend the AndroidViewModel class and have a constructor that receives the Application in the constructor.

Now we modify UserListsFragment to observe the data and update the UI.

If the activity is re-created, it receives the same UserViewModel instance that was created by the previous activity. When the owner activity is finished, the Framework calls ViewModel’s onCleared() method so that it can clean up resources.

Sharing Data Between Fragments

Imagine a common case of master-detail fragments, where we have a fragment in which the user selects an item from a list and another fragment that displays the contents of the selected item.

ViewModels can be used as a communication layer between different Fragments of an Activity. Each Fragment can acquire the ViewModel using the same key via their Activity. This allows communication between Fragments in a de-coupled fashion such that they never need to talk to the other Fragment directly.

These fragments can share a ViewModel using their activity scope to handle this communication.

Now we modify UserListFragment to share the data.

Notice that both fragments are using getActivity() while getting the ViewModelProvider. This means both of them will receive the same SharedViewModel instance which is scoped to the activity.

Lifecycle of a ViewModel

ViewModel objects are scoped to the Lifecycle passed to the ViewModelProvider when getting the ViewModel. The ViewModel stays in memory until the Lifecycle it’s scoped to goes away permanently—in the case of an activity, once it finishes; in the case of a fragment, once it’s detached.

viewmodel lifecycle

Download this project from GitHub.

Related Post

Lifecycle Aware Components

Room Persistence Library

LiveData

Fragment Tricks

ConstraintLayout 1.1.x

Lifecycle Aware Components

Lifecycles

Lifecycle is the biggest developer pain point. Lifecycle is hard. Lifecycle aware observable things that can do something base on the lifecycle. Your application must respect components lifecycles. Not doing so may trigger memory leaks or even application crashes.

Imagine we have an activity that shows the device location on the screen.

What if myLocationManager.addLocationListener() will be called after myLocationManager.removeLocationListenrer() called, basically keeping the connection forever.

Lifecycle aware component

Components

New lifecycle-aware components provide constructs to tie core components(activity, fragment) of your applications to lifecycle events, removing explicit dependency paths.It can take care of itself. You can just initialize it and forget about it.

Lifecycle

Lifecycle is a class that holds the information about the lifecycle state of a component (like an activity or a fragment) and allows other objects to observe this state.

Lifecycle Components

LifecycleOwner

This is a thing with a lifecycle, it is your activity or your fragment or maybe you have your own UI framework.There as a lifecycle Owner.

LifecycleObserver

LifecycleObserver is the thing that cares about the Lifecycle.Like the LocationManager. It cares about the lifecycle, it wants to stop itself if the lifecycle is not active.

A class can monitor the component’s lifecycle status by adding annotations to its methods.

Now, we initialize MyLocationManager with our Lifecycle(MainActivity) on onCreate and stop worrying about it afterwards. This allows MyLocationManager class to be self sufficient, meaning that it can do its own cleanup when necessary.

Passes the LifecycleOwner as the first argument.

Adding Lifecycle to your Project

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

Add the Google Maven repository

To add it to your project, open the build.gradle file for your project and add the highlighted line as shown below:

Add Architecture Components

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

Order of LifecycleObserver

if observer1 is added before observer2, then ON_CREATE is sent first to observer1, then to observer2 (same happens for ON_START and ON_RESUME), but ON_PAUSE event is sent first to observer2 and only then to observer1 (same for ON_STOP and ON_DESTROY).

 

Download this project from GitHub.

Related Post

ViewModel

Room Persistence Library

LiveData

Fragment Tricks

ConstraintLayout 1.1.x