blog posts

MVVM Android Architecture Programming !

Currently, it can be said that MVVM architecture in Android is the best architecture to implement applications against architectures such as MVP or MVC. This tutorial will discuss and implement the Android MVVM architecture template in our Android application. We have already discussed the MVP architecture pattern in Android.

Types of architecture in Android

(MVVM (Model, View, View Model

(MVP (Model, View, Presenter)

(MVC (Model, View, Controller)

What is the MVVM architecture?

MVVM stands for Model, View, ViewModel.

Model, View, ViewModel (MVVM) is a program architecture template proposed by John Gusman as an alternative to MVC and MVP templates when using Data Binding technology. First, we consider this template’s description and analyze each of its components. MVVM is a software architecture design template that facilitates the separation of the user interface from the business logic and the application’s data model.

MVVM training in Android

Model

The model layer can include data access (Repository, repositories, APIs), Entity classes, etc. The model is a data provider for updating data. Data can be retrievable from various sources, for example:

  • REST API
  • Realm DB
  • SQLite DB
  • Handles broadcast
  • Shared Preferences
  • Firebase
  • And, etc.

The model does not know anything about View or ViewModel and exists independently. If you transfer an Android application on the MVC or MVP template to MVVM, the model layer will probably not need to be change.

View

The view is what the user sees, and in Android programming, views are typically definable in XML. And are mostly observable in the Fragment, Activity, or View classes. In many Android applications, code unrelatable to View, especially business logic, is often confusable with Fragments and Activities. Which can be very difficult to develop or maintain.

MVVM tackles this problem by keeping Fragments and Activities only as part of the View layer. They just have to set the view and connect the ViewModel to the View (with tools like RxJava).

Unlike View, MVC has no model information. view is only aware of the ViewModel with which it fills in its data for display.

The view must be free of display logic (date formatting, rules for showing / hiding an element, etc.), which will be present in ViewModel instead. The view can request the ViewModel to operate, which may usually update the model based on user input.

For example, View is responsible for handling the following topics:

  • Menus
  • Permissions
  • Event listeners
  • Showing dialogs, Toasts, Snack bars
  • Working with Android View and Widget
  • Start Activities
  • All functionality that is related to the Android Context

ViewModel

ViewModel contains the data required for View. As the name implies, the ViewModel is the View and the Model bridge. Extracts its data from the model layer and converts it for display. ViewModel maintains the active state of the program. Exposes this operation to the View and provides the interface for updating the model. ViewModels are a kind of POJO, which means that they are easily testable, one of their main advantages.

ViewModel has the following responsibilities:

  • Exposing data
  • (Exposing state (progress, offline, empty, error, etc
  • Handling visibility
  • Input validation
  • Executing calls to the model
  • Executing methods in the view

ViewModel only needs to know about the Context of the application. Context The program can include:

  • Start a service
  • Bind to a service
  • Send a broadcast
  • Register a broadcast receiver
  • Load resource values

And may not include the following:

  • Show a dialog
  • Start an activity
  • Inflate a layout

Difference between MVVM and MVP:

  • ViewModel sits in the middle layer instead of the Presenter.
  • The presenter refers to View. ViewModel is not like this.
  • ViewModel sends data streams.
  • Presenter and View are in a 1: 1 relationship.
  • View and ViewModel are in a 1-to-many relationship.
  • ViewModel does not know that View is listening.

Difference between MVVM and MVC:

MVVM has several concepts with the more common model (MVC) Model View Controller, so those who are already familiar with or have worked with MVC should be able to work with MVVM easily. What is different is how they communicate and how they are aware of each other.

Benefits of MVVM

Viewmodels make Display Logic easier to test:

Viewmodels allow screen logic to be tested without being seen moment by moment. Android development allows more tests to be written in JUnit and run locally, not in Android JVM (emulator or device), meaning that the tests run much faster.

Separation of relations:

Fragile code causes program maintenance nightmares. Suppose we start developing an application without any architecture. In that case, we will cause more errors in the program, and when we want to add a new feature to the program, we will be confused. So the speed of program development will be very slow and will cause the customer to be dissatisfied with the program development process. One of the most important benefits that we often see in Android applications is the integrated Activities and Fragments that include business logic and direct interaction with the database or API, which comes with all the View code. Also MVVM helps maintain a clean, consistent, and fully paired architecture, keeping Activities and Fragments merely part of The View.

Improves code reuse:

Viewmodels can be reused throughout the application, meaning that display logic does not need to be copied. This view can even be moved to another location and still uses the same ViewModel and uses the same ViewModel as long as it depends on the same data and operations.

The user interface can be updated without touching Business Logic:

This means that fewer manufacturers can work on components with fewer conflicts, making it easier to increase team numbers. For example, a front-end developer can work independently on View without the need for logic in ViewModel. In contrast, another developer can work on another part, and a fake version of a ViewModel can be used. At the same time, the original version is in development.

Two ways to implement MVVM on Android:

In this article, we will use Data Binding.
Google introduced the Data Binding Library to link data directly in the XML Layout.

We want to create a simple example of a log-in program that requests input from a user. We will see how the ViewModel notifies the View when to display the message (Toast) without holding or referring to the View.

How can I inform some classes without referring to them?

This can be in three different ways:

  •  Using Two Way Data Binding
  •  Also Using LiveData
  •  Using RxJava

Two Way Data Binding:

Two Way Data Binding is a technique for connecting your objects to the XML Layout so that Object and Layout can send both data to each other.

In our example, ViewModel can send data to the layout and view changes.

We need a BindingAdapter and custom attribute defined in XML to do this.

BindingAdapter can listen for feature changes.

Learn more about Two Way Data Binding through the example below.

Example of the MVVM project structure in Android:

MVVM on Android

Add Data Binding Library

Add the following code to your build. gradle file:
android {
    dataBinding {
        enabled = true
    }
}
This feature enables Data Binding in your application.

Add dependencies

Add the following dependencies to your build. gradle file:
implementation 'android.arch.lifecycle: extensions: 1.1.0'

Model

Holds the user’s email and password model. The User.java class does this:

package com. journaldev . androidmvvmbasics . model ;
public class  User {
    private String email;
    private String password;
    public User ( String email, String password) {
         this . email = email;
        this . password = password;
    }
    public void  setEmail ( String email ) {
         this . email = email;
    }
    public String  getEmail () {
         return email;
    }
    public void  setPassword ( String password ) {
         this . password = password;
    }
    public String  getPassword () {
         return password;
    }
}

Two Way Data Binding allows us to link objects in the XML Layout so that the Object can send the data to the Layout and vice versa.

Nt Syntax For Two Way Data Binding @ = {variable

Layout

The code for activity_main.xml is as follows:

<? xml version = "1.0" encoding = "utf-8"?> 
< layout  xmlns: android = "https://schemas.android.com/apk/res/android" 
    xmlns: bind = "https: // schemas .android.com / tools " > 
    < data > 
        < variable 
            name = " viewModel " 
            type = " com.journaldev.androidmvvmbasics.viewmodels.LoginViewModel " /> 
    </ data > 
    < ScrollView 
        android: layout_width = " match_parent " 
        android: layout_height = "match_parent" >
        < LinearLayout 
            android: layout_width= "match_parent" 
            android: layout_height = "wrap_content" 
            android: layout_gravity = "center" 
            android: layout_margin = "8dp" 
            android: orientation = "vertical" > 
            < EditText 
                android: id = "@ + id / inEmail" 
                android: layout_width = "match_parent" 
                android: layout_height = "wrap_content" 
                android: hint = "Email" 
                android: inputType = "textEmailAddress" 
                android: padding = "8dp"
                android: text = "@ = {viewModel.userEmail}"/> 
            < EditText 
                android: id = "@ + id / inPassword" 
                android: layout_width = " match_parent" 
                android: layout_height = "wrap_content" 
                android: hint = "Password" 
                android: inputType = "textPassword" 
                android: padding = "8dp" 
                android: text = "@ = {viewModel.userPassword}" /> 
            < Button 
                android: layout_width = "match_parent" 
                android: layout_height = "wrap_content" 
                android: layout_marginTop = "8dp " 
                android: onClick ="@ {() -> viewModel.onLoginClicked ()}" 
                android: text = "LOGIN" 
                bind: toastMessage = "@ {viewModel.toastMessage}" /> 
        </ LinearLayout > 
    </ ScrollView > 
</ layout >

Here our ViewModel connects the data to the View. ViewModel.onLoginClicked () () This button is defined and called lambda in ViewModel.

ViewModel

The LoginViewModel.java login code is as follows:

package com. journaldev . androidmvvmbasics . viewmodels ;
import android. databinding . BaseObservable ;
import android. databinding . Bindable ;
import android. text . TextUtils ;
import android. util . Patterns ;
import com. android . databinding . library . baseAdapters . BR ;
import com.journaldev . androidmvvmbasics . model . User ;
public class  LoginViewModel  extends  BaseObservable {
    private User user;
    private String successMessage = "Login was successful" ;
    private String errorMessage = "Email or Password not valid" ;
    @ Bindable 
    private String toastMessage = null ;
    public String  getToastMessage () {
         return toastMessage;
    }
    private void  setToastMessage ( String toastMessage ) {
         this . toastMessage = toastMessage;
        notifyPropertyChanged ( BR . toastMessage );
    }
    public void  setUserEmail ( String email ) {
        user. setEmail (email);
        notifyPropertyChanged ( BR . userEmail );
    }
    @ Bindable 
    public String  getUserEmail () {
         return user. getEmail ();
    }
    @ Bindable 
    public String  getUserPassword () {
         return user. getPassword ();
    }
    public void  setUserPassword ( String password ) {
        user. setPassword (password);
        notifyPropertyChanged ( BR . userPassword );
    }
    public LoginViewModel () {
        user = new  User ( "" , "" );
    }
    public void  onLoginClicked ()
         ( if ( isInputDataValid ())
             setToastMessage (successMessage);
        else 
            setToastMessage (errorMessage);
    }
    public boolean isInputDataValid () {
         return ! TextUtils . isEmpty ( getUserEmail ()) && Patterns . EMAIL_ADDRESS . matcher ( getUserEmail ()). matches () && getUserPassword (). length ()> 5 ;
    }
}

The above class can also extend ViewModel. But we need BaseObservable because it converts data into a stream and gets notified when the toastMessage property changes.

For the custom toastMessage attribute defined in XML, we need to define Setter and Getter.

Inside the Setter, we notify the Observer that the data has changed. Our view (our activity) can define the appropriate action.

The MainActivity.java class code is as follows:

package com. journaldev . androidmvvmbasics . views ;
import android. databinding . BindingAdapter ;
import android. databinding . DataBindingUtil ;
import android. support . v7 . app . AppCompatActivity ;
import android. os . Bundle ;
import android. view . View ;
import android. widget .Toast ;
import com. journaldev . androidmvvmbasics . R ;
import com. journaldev . androidmvvmbasics . databinding . ActivityMainBinding ;
import com. journaldev . androidmvvmbasics . viewmodels . LoginViewModel ;
public class  MainActivity  extends  AppCompatActivity {
    @ Override 
    protected void  onCreate ( Bundle savedInstanceState ) {
         super . onCreate (savedInstanceState);
        ActivityMainBinding activityMainBinding = DataBindingUtil . setContentView ( this , R. layout . activity_main );
        activityMainBinding. setViewModel ( new  LoginViewModel ());
        activityMainBinding. executePendingBindings ();
    }
    @ BindingAdapter ({ "toastMessage" })
    public static  void  runMe ( View view, String message ) {
         if (message! = null )
             Toast . makeText (view. getContext (), message, Toast . LENGTH_SHORT ). show ();
    }
}

Thanks to DataBinding, the ActivityMainBinding class of the Layout is created automatically. The BindingAdapter method is activated when the toastMessage properties defined in the button change. Must use the same attribute as defined in XML and ViewModel.

So in the above program, ViewModel updates the model by listening to the changes in View. Also, the model can update the View via ViewModel using notifyPropertyChanged.

You can see the output of the above program below.

MvvM on Android

You can download the MVVM training project on Android using DataBinding from the link below.

Another example of MVVM in Android

The program is very simple. It brings the top Reddit posts from its JSON API and displays them in a list.
The following libraries are used in this example:
  • RxJava
  • Retrofit
  • Dagger 2
  • Picasso
  • AndroidAnnotations
  • Lombok

You can see this example at the following link:

Github (Mvvm-Reddit)

Conclusion:

In this article, we got acquainted with the MVVM architecture in Android. We compared it with MVC architecture and MVP architecture. We got acquainted with the features and performance of MVVM and realized that using it is very useful. And gives a general path to our application and makes it very easy for us to add a new feature to our program, gives high testability, and Improves program maintenance.