Getting started with android architecture components and MVVM Part-1

Shahbaz Ahmed
AndroidPub
Published in
5 min readMay 26, 2017

There were some interesting stuff at this year’s Google I/O 17. One such session was Architecture Components — Introduction by Yigit Boyar and Luke Bergstorm. The announcement included new architecture components library.

What’s Android architecture components

A new collection of libraries that help you design robust, testable, and maintainable apps. Start with classes for managing your UI component lifecycle and handling data persistence.

The architecture components come with lot of new components such as LiveData, ViewModel, LifecycleObserver and LifecycleOwner and Room Persistence library. Together these components would help developers follow the right architecture pattern with proper separation of responsibility for each layer (more on that later) and help survive configuration changes, avoid memory leaks and updating the UI in case of changes in our data.

  1. LifecycleOwner — Interface for components having Lifecycle (such as Activities and Fragments).
  2. LifecycleObserver — LifecycleObserver subscribes to LifecycleOwner’s lifecycle state changes and are self sufficient. It does not have to rely on Activity or fragment’s onStart() or onStop() lifecycle callback to initialise and stop it.
  3. LiveData — It is an observable data holder, it notifies the observers in case of data changes. It is also lifecycle aware component i.e. it respects the lifecycle state of the LifecycleOwner (Activities or Fragments). This helps preventing memory leaks and other issues.
  4. ViewModel- Objects that provide data for the UI components. They does not have the references to the view and are unaffected by the life-cycle of LifecycleOwner.
  5. Room — SQLite based object mapping library. Room abstracts the underlying layer of implementation details like creating and managing database and tables. Room uses annotations to generate code at compile time. Furthermore Room also supports LiveData and Rx Java 2 Flowables

MVVM Pattern using Architecture components

To demonstrate the MVVM architecture pattern, let’s create a simple android app to fetch the issues of any github repository. In this post We will be mostly be covering ViewModel and LiveData components.

Picture from: Android developers site

We will be having the following component layers:

  1. View — This layer contains UI components and is responsible for view related code such as initialising child views, displaying progress bar, receiving input from user and handling animations, etc. Example: Activities and Fragments.
  2. ViewModel — ViewModels provide data to the UI components. In our case views will be using LiveData to observe the data changes in ViewModel.
  3. Repository — Repositories abstract the underlying implementation of Data sources that an app can use cache and fetch the data. This abstraction is helpful in two ways: 1) the code is not dependent on the concrete implementation of data store, and 2) Because of previous point, we can swap the implementation of datastore at any time such as for testing.
  4. Data Service — This layer contains the actual code that caches (by using SQLite for example) or fetches data (like by fetching data from backend api’s using retrofit).

Recommended Article

Enough of talk. Let’s Code

It is assumed that you have some understanding of retrofit. The code described below can be found in my github here.

Open project level build.gradle file and add the following:

Add the retrofit 2 and architecture components dependencies to app level build.gradle file.

Next we will create the entities.

Enter the following URL in your browser https://api.github.com/repos/square/retrofit/issues to get a list of JSON objects. Grab one one JSON object and head to the following site: jsonschema2pojo and paste the copied JSON object in the text area. Select source type as JSON and Annotation Style as GSON since we will be using GSON converter to convert JSON to entity.

Now click preview and grab the generated code. Create 2 entities Issue and User.

Next, lets create another entity ApiResponse.

We will use ApiResponse to communicate data from Repository to ViewModel and ultimately to Activity. So if we get any error while fetching data from the remote api, we will set Error in the ApiResponse, else we will set the list of Issue objects into it.

Next let’s create Retrofit Service interface:

Next, we’ll create Repository. First lets create IssueRepository interface

Now we’ll create IssueRepositoryImpl which implements IssueRepository interface. As discussed above Repositories are used to abstract the communication of rest of the code to the Data sources (such as Database or API calls). In our case IssueRepositoryImpl will use GithubApiService to fetch data from github API and return the value as a LiveData.

In the getIssues() method we create a MutableLiveData from the data obtained from retorfit. MutableLiveData is the subclass of LiveData that has setValue(T) method that can be used to modify the value it holds.

Next let’s create our ViewModel class named ListIssuesViewModel which extends ViewModel abstract class:

ListIssuesViewModel will fetch the data requested by the UI from the IssueRepository. It has MediatorLiveData mApiResponse which is observed by the UI. MediatorLiveData is a subclass of MutableLiveData which allows us to observe one or more LiveData (LiveData from Repository’s getIssues() method in our case) and propagate the changes to it own observers (Activity in our case).

Note:

  1. In case you want to have a ViewModel class with non-empty constructor, you have to create a Factory class which would create instance of you ViewModel and that Factory class has to implement ViewModelProvider.Factory interface.
  2. If you want reference to Application context in your View Model class, you can use AndroidViewModel class instead of ViewModel class.

Finally, create an activity which extends AppCompatActivity class (Since LifecycleActivity has been deprecated as of version architecture components 1.0.0-alpha9–1 and both AppCompatActivity and Support Fragment now implement the LifecycleOwner interface) with EditText and Recycler View. Make sure to upgrade your support library version to 26.1.0 (latest as of the time of writing) as this is the required dependency for architecture components library. In onCreate() we will intialize the ViewModel, observe the MediatorLiveData property mApiResponse and take appropriate action to display the view. If user initiates a new search query, we will call viewModel. loadIssues(@NonNull String user, String repo) method with appropriate parameters.

So we now have an app which uses android recommended architecture pattern by using MVVM, LiveData and Repository. Thanks for ViewModel class, our app also persists data across configuration changes such as screen rotations.

Our app in action

What’s next

Android developer’s Guide to app architecture suggests using Dagger 2 library for dependency injection and Room ORM for data persistence.

If you liked this article, please recommend it by pressing 💚 button.

In the next post we will check out how to use Dagger 2 for managing Dependency Injection in our app.

Originally published at shahbaz.co on May 26, 2017.

--

--