MOHD SAQUIB
8 min readMay 5, 2018

Consuming REST API using Retrofit Library with the help of MVVM, Dagger 2, LiveData and RxJava 2 in Android

Image by developer.android.com

This blog is all about implementing REST API in the Android app using Retrofit Library by using MVVM , RxJava 2, Android Architecture Components introduce by Google and Dagger 2 which make our code more clear and reusable and easy to modify if needed.

Most of the Android developer have a habit to write more than thousand line boilerplate code in single activity/fragment without using any design pattern. So its time to improve coding standard by using new API like RxJava, dagger and etc. that is already introduced for application building. So before using Retrofit(for rest API call), we should have known about what basically MVVM, Dagger, and RxJava are. The first question comes to our mind that what does mean and use of MVVM. So Let’s start with MVVM.

There are three parts of the Model-View-ViewModel architecture:

  1. Model is used to write Business logic. The model represents the actual data and/or information we are dealing with.
  2. View is used to consume data/result received from ViewModel and inform ViewModel of user interaction.In simple way, we can say that it is used to display data to user.
  3. ViewModel works as a bridge between Model and View. It is responsible to process data using Model and send back the result to View to consume it. It contains UI Logic that involving both View and Model. A ViewModel is retained as long as the scope of its Activity/Fragment is alive, including when the Activity/Fragmentis destroyed and recreated due to a configuration change; This allows ViewModel to make UI data available to the recreated activity or fragment instance. Wrapping UI data stored within the ViewModel with LiveData provides the data an observable lifecycle-aware home.

You can see MVVM app archeture flow from attached image on top.

Now start building an app using this.A quick look at the Gradle of the app.

View
Here We use LoginActivity as View which subscribe to receive basically three event while intracting with ViewModel.
1. Start rest api intraction
2. Get result from rest api
3. Get any kind of error while process

We can see here the main purpose of LoginActivity is to call rest API and consume its response. Now you can see a lot of interesting thing in this code such as annotation like @Inject, @BindView and ViewModelFactory and LoginViewModel etc. so don’t get bored or panic I will explain it properly one by one before going forward in code.

First thing lets see about @Inject this annotation is used for injecting object, now an interesting point injecting of the object comes to mind what that means.So That means you create the object once and reuse it throughout your application where required and in this by just inject that object, there is a lot of way of dependency injection but here we will use Dagger API.

I used here dagger:2.13, you can learn more from this article about dagger.

See how we will use the dagger in our application. Look at UtilsModule.java and AppModule.java classes.

(UtilsModule.java)
(AppModule.java)

You have to create a module class using annotation @Module which will create objects by using @Provides and @Singleton annotation. I created here few objects what is needed for this project. For consuming rest API you need to have the retrofit object so I create here Retrofit object and we will inject it wherever it needed like “@Inject Retrofit retrofit;”.

Now look at the ViewModelFactory class.

Repository class is injected here and it passes into LoginViewModel constructor for its further use, so we will save our time of making Repository class object in LoginViewModel which is actually a ViewModel, this class used repository object for implementing business logic. Now let’s have a look at LoginViewModel and Repository classes.

First, see LoginViewModel which is used as ViewModel for LoginActivity.

Here we go with a lot of new amazing things like CompositeDisposable, MutableLiveData etc. Don’t get panic I will explain it what purpose of these object. First, see in above class that is extended by ViewModel which has some its callback function like onCleared().

ViewModel is part of MVVM design pattern which we have already discussed in starting. But few interesting things about it is that ViewModel class is designed to store and manage UI related data in a lifecycle conscious way. It allows data to survive even in the configuration change.

If the system recreated UI, for example, you rotate your screen then activity get recreated in such case before ViewModel concept you generally used to use onSaveInstanceState() and restore its data by using bundle in onCreate() this process was suitable for small amount of data that you can easily be serialized and deserialized, another problem that supposes you make an asynchronous call that is taking some time to return data then UI controller needs to manage these call and ensure the system cleans them up after it’s destroyed to avoid memory leaks. To handle all these problems you can easily use ViewModel which is lifecycle aware and it will manage this kind of UI related problem.

Now comes to code again here we used CompositeDisposable which is a concept of RxJava.

disposables.add(repository.executeLogin(mobileNumber, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe((d) -> responseLiveData.setValue(ApiResponse.loading()))
.subscribe(
result -> responseLiveData.setValue(ApiResponse.success(result)),
throwable -> responseLiveData.setValue(ApiResponse.error(throwable))
));

I made REST API call using RxJava instead of any thread or async task. So let’s discuss few things about RxJava.
What is RxJava?
“RxJava is a Java VM implementation of Reactive Extensions. It has become the single most important skill for Android development.”

RxJava works on Observer pattern. It has basically three major component.
1.Observable
2.Subscriber
3.Observer

To understand it in better way go to this “link”.

In our code we used subscribe() this means where we want to subscribe process generally we use IO thread by using Schedulers.io(), the second function is observeOn() which indicate where user wanted to consume data comes from observable and where we want to consume it in our case we use MainThread by using AndroidSchedulers.mainThread().
We use CompositeDisposable to add each subscription and clear this inside onCleared() callback of ViewModel.
Now comes to MutableLiveData, before understanding MutableLiveData first let’s have a look of LiveData.

What is LiveData?
LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state. For More information go to this “article” or “this.

The advantages of using LiveData
1
.Ensures your UI matches your data state.
2.
No memory leaks.
3.
No crashes due to stopped activities.
4.
No more manual lifecycle handling.
5.
Sharing resources.

LiveData has no publicly available methods to update the stored data. So basically we need MutableLiveData.
The MutableLiveData class exposes the setValue(T)and postValue(T)methods publicly and you must use these if you need to edit the value stored in a MutableLiveData object. Usually, MutableLiveData is used in the ViewModel and then the ViewModel only exposes immutable MutableLiveData objects to the observers. We are setting value in MutableLiveData object like:

responseLiveData.setValue(ApiResponse.loading())

Now its time to move further in code, we used Repository class here you can see the implementation of this class here.

In this class, we are using the ApiCallInterface object which is used to call REST API. ApiCallInterface is created in UtilsModule.

@Provides
@Singleton
ApiCallInterface getApiCallInterface(Retrofit retrofit) {
return retrofit.create(ApiCallInterface.class);
}

and we are passing ApiCalInterface object in repository class using same UtilsModule class.

@Provides
@Singleton
Repository getRepository(ApiCallInterface apiCallInterface) {
return new Repository(apiCallInterface);
}

Now I hope it would be more clear now so comes to next implementation.
Here we use ApiCallInterface which is basically class which includes the function to hit REST API using Retrofit. You can see its implementation here.

and Urls.java is:

Here BASE_URL which is use while creating retrofit object in UtilsModule.
Urls.LOGIN is your endpoint.

@Provides
@Singleton
Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Urls.BASE_URL)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();

return retrofit;
}

Now most important class is used for data transfer is ApiResponse.java

and Status class is nothing but enum class. It is use just for status of response.

Now come to the LoginActivity.java class again which is our View as we discussed this activity at the starting.

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
progressDialog = Constant.getProgressDialog(this, "Please wait...");
ButterKnife.bind(this);
((MyApplication) getApplication()).getAppComponent().doInjection(this);

viewModel = ViewModelProviders.of(this, viewModelFactory).get(LoginViewModel.class);

viewModel.loginResponse().observe(this, new Observer<ApiResponse>() {
@Override
public void onChanged(@Nullable ApiResponse apiResponse) {
consumeResponse(apiResponse);
}
});


}

First see this code here we bind this activity with AppComponent for using injecting object defined in UtilsModule.java class.
AppComponent interface is :

AppComponet interface work here as a bridge between Modules and our activity. It comes under dagger concept.

To implement Dagger we have to bind AppComponent with the application here we use application class to achieve this.

To create appComponent object we have to use code written in onCreate()
appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).utilsModule(new UtilsModule()).build();
For this You have to just add Dagger in name before your component class like DaggerAppComponent and after this just build the project to remove error like “can not resolve” at DaggerAppComponent. For more information read “dagger article ”.

After these things let’s look at the remaining point of LoginActivity.

viewModel = ViewModelProviders.of(this, viewModelFactory).get(LoginViewModel.class);

viewModel.loginResponse().observe(this, new Observer<ApiResponse>() {
@Override
public void onChanged(@Nullable ApiResponse apiResponse) {
consumeResponse(apiResponse);
}
});

In the above code, we have created an object of LoginViewModel using viewModelFactory object and we call loginResponse() function of our viewmodel class and observe it because return type of loginResponse() function is of type MutableLiveData, so whenever we make any changes in MutableLiveData object by using setValue() or postValue() function will onChanged() function will always be called.In this function we will consume response coming from apiResponse. Here consumeResponse function is:

/*
* method to handle response
* */
private void consumeResponse(ApiResponse apiResponse) {

switch (apiResponse.status) {

case LOADING:
progressDialog.show();
break;

case SUCCESS:
progressDialog.dismiss();
renderSuccessResponse(apiResponse.data);
break;

case ERROR:
progressDialog.dismiss();
Toast.makeText(LoginActivity.this,getResources().getString(R.string.errorString), Toast.LENGTH_SHORT).show();
break;

default:
break;
}
}
/*
* method to handle success response
* */
private void renderSuccessResponse(JsonElement response) {
if (!response.isJsonNull()) {
Log.d("response=", response.toString());
} else {
Toast.makeText(LoginActivity.this,getResources().getString(R.string.errorString), Toast.LENGTH_SHORT).show();
}
}

Here we can get three type of response either Loading , success or error.We manage our UI according to this and consume its data in case of success and parse JsonElement response in my case using Gson.

That was all about this article, you can refer these article for more knowledge.
1. https://medium.com/google-developers/lifecycle-aware-data-loading-with-android-architecture-components-f95484159de4
2. https://medium.com/mindorks/tagged/rxjava
3. https://medium.com/@kurtisnusbaum/rxandroid-basics-part-1-c0d5edcf6850
4. https://developer.android.com/topic/libraries/architecture/livedata
5.https://medium.com/upday-devs/android-architecture-patterns-part-3-model-view-viewmodel-e7eeee76b73b
6.http://square.github.io/retrofit/

Do find the full source code from here:
https://github.com/saquib3705/MVVMWithDaggerAndRxJavaAndroid.git

Happy Coding….
Thanks & Regards

Let’s become friends on Linkedin and Facebook.