Best android app development wiBest mobile app development and design company. Best e-commerce development company.

Android Architecture.

Android architecture, helps to attain a proper structure for the code. It has three different types of architecture patterns followed in Android are:

  • MVC (Model View Controller)
  • MVP (Model View Presenter)
  • MVVM (Model View ViewModel)

MVC (Model View Controller)

Model View Controller is an architecture pattern that tells to separate code for Android applications into 3 layers which are as follows −

  • Model − The model is responsible for handling data used within our application. It is also responsible for communicating and gathering data from a network or database.
  • View − View layer the name itself tells us to display a view to the user. Also, it manages the UI of the Android application which is visible to the end user.
  • Controller − The controller in MVC contains the core logic of the Android application used to read and write the data from our Model layer and set this data in our UI layer to display it to the user.
Android app development

Advantages of using MVC Pattern

  • Unit testing of the Model and Controller class is possible using the MVC pattern.
  • MVC patterns provide functionality to separate model classes which makes it easier to implement new features.

Disadvantages of using MVC Pattern

  • The code layers are dependent on each other. For example, the UI layer is dependent on the Model layer to get the data and display it in the UI layer.

Example Code

1: Create a new project

2: Modify String.xml file.
String.xml

<resources>
	<string name="app_name">MVC Architecture</string>
	<string name="Heading">MVC Architecture Pattern</string>
	<string name="Text1">Button_1</string>
	<string name="count">Count:0</string>
</resources>

3: Open the activity main.xml file and add 3 buttons.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="https://schemas.android.com/apk/res/android"
	xmlns:app="https://schemas.android.com/apk/res-auto"
	xmlns:tools="https://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:background="#168BC34A"
	tools:context=".MainActivity" >

	<!-- Provided Linear layout for the activity. -->
	<LinearLayout
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:orientation="vertical"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent">

		<!-- TextView to display heading of the activity. -->
		<TextView
			android:id="@+id/textView"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginTop="40dp"
			android:layout_marginBottom="60dp"
			android:fontFamily="@font/roboto"
			android:text="@string/Heading"
			android:textAlignment="center"
			android:textColor="@android:color/holo_green_dark"
			android:textSize="30sp"
			android:textStyle="bold" />

		<!-- First Button of the activity. -->
		<Button
			android:id="@+id/button"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginStart="20dp"
			android:layout_marginTop="30dp"
			android:layout_marginEnd="20dp"
			android:layout_marginBottom="20dp"
			android:background="#4CAF50"
			android:fontFamily="@font/roboto"
			android:text="@string/count"
			android:textColor="@android:color/background_light"
			android:textSize="24sp"
			android:textStyle="bold" />

		<!-- Second Button of the activity. -->
		<Button
			android:id="@+id/button2"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginStart="20dp"
			android:layout_marginTop="50dp"
			android:layout_marginEnd="20dp"
			android:layout_marginBottom="20dp"
			android:background="#4CAF50"
			android:fontFamily="@font/roboto"
			android:text="@string/count"
			android:textColor="@android:color/background_light"
			android:textSize="24sp"
			android:textStyle="bold" />

		<!-- Third Button of the activity. -->
		<Button
			android:id="@+id/button3"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginStart="20dp"
			android:layout_marginTop="50dp"
			android:layout_marginEnd="20dp"
			android:layout_marginBottom="20dp"
			android:background="#4CAF50"
			android:fontFamily="@font/roboto"
			android:text="@string/count"
			android:textColor="@android:color/background_light"
			android:textSize="24sp"
			android:textStyle="bold" />

		<ImageView
			android:id="@+id/imageView"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginTop="30dp"
			app:srcCompat="@drawable/banner" />
		
	</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

4: Creating the Model Class

import java.util.*;

public class Model extends Observable {

	// declaring a list of integer
	private List<Integer> List;

	// constructor to initialize the list
	public Model(){
		// reserving the space for list elements
		List = new ArrayList<Integer>(3);

		// adding elements into the list
		List.add(0);
		List.add(0);
		List.add(0);
	}

	// defining getter and setter functions

	// function to return appropriate count
	// value at correct index
	public int getValueAtIndex(final int the_index) throws IndexOutOfBoundsException{
		return List.get(the_index);
	}

	// function to make changes in the activity button's
	// count value when user touch it
	public void setValueAtIndex(final int the_index) throws IndexOutOfBoundsException{
	List.set(the_index,List.get(the_index) + 1);
	setChanged();
	notifyObservers();
	}

}

5: Define functionalities of View and Controller in the MainActivity file

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import java.util.Observable;
import java.util.Observer;


public class MainActivity extends AppCompatActivity implements Observer, View.OnClickListener {


	// creating object of Model class
	private Model myModel;


	// creating object of Button class
	private Button Button1;
	private Button Button2;
	private Button Button3;




	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);


		// creating relationship between the
		// observable Model and the
		// observer Activity
		myModel = new Model();
		myModel.addObserver(this);


		// assigning button IDs to the objects
		Button1 = findViewById(R.id.button);
		Button2 = findViewById(R.id.button2);
		Button3 = findViewById(R.id.button3);




		// transfer the control to Onclick() method
		// when a button is clicked by passing
		// argument "this"
		Button1.setOnClickListener(this);
		Button2.setOnClickListener(this);
		Button3.setOnClickListener(this);


	}


	@Override
	// calling setValueAtIndex() method
	// by passing appropriate arguments
	// for different buttons
	public void onClick(View v) {
		switch(v.getId()){


			case R.id.button:
				myModel.setValueAtIndex(0);
				break;


			case R.id.button2:
				myModel.setValueAtIndex(1);
				break;


			case R.id.button3:
				myModel.setValueAtIndex(2);
				break;
		}
	}


	@Override
	// function to update the view after
	// the values are modified by the model
	public void update(Observable arg0, Object arg1) {




		// changing text of the buttons
		// according to updated values
		Button1.setText("Count: "+myModel.getValueAtIndex(0));
		Button2.setText("Count: "+myModel.getValueAtIndex(1));
		Button3.setText("Count: "+myModel.getValueAtIndex(2));


	}
}

MVP (Model View Presenter)

Model View Presenter is an architecture pattern that separated code for Android applications into 3 layers which are as follows −

  • Model − The model layer is used to store the data which is being used within our application. The data can be gathered either from the network or the database of the application.
  • View − View is a UI interface layer that provides visualization of data to keep track of actions to notify users of actions to present to the presenter.
  • Presenter − The presenter in MVP is used to fetch the data from the Model and display it in the UI according to the user interaction with the application.

Advantages of using MVP Pattern

  • In MVP the model, view, and presenter layer are separated which makes it easy to test the code.
  • MVP doesn’t have any relationship with Android components.

Example Code

1: Create a new project

2: Modify String.xml file

<resources>
	<string name="app_name">MVP Architecture</string>
	<string name="buttonText">Display Next Course</string>
	<string name="heading">MVP Architecture Pattern</string>
	<string name="description">Course Description</string>
</resources>

3: Working with the activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
	xmlns:android="https://schemas.android.com/apk/res/android"
	xmlns:app="https://schemas.android.com/apk/res-auto"
	xmlns:tools="https://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:background="#168BC34A"
	tools:context=".MainActivity">

	<!-- TextView to display heading of the activity -->
	<TextView
		android:id="@+id/textView3"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:fontFamily="@font/roboto"
		android:text="@string/heading"
		android:textAlignment="center"
		android:textColor="@android:color/holo_green_dark"
		android:textSize="30sp"
		android:textStyle="bold"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintHorizontal_bias="0.498"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toTopOf="parent"
		app:layout_constraintVertical_bias="0.060000002" />
	
	<!-- TextView to display the random string -->
	<TextView
		android:id="@+id/textView"
		android:layout_width="411dp"
		android:layout_height="wrap_content"
		android:fontFamily="@font/roboto"
		android:gravity="center"
		android:padding="8dp"
		android:text="@string/description"
		android:textAlignment="center"
		android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
		app:layout_constraintBottom_toTopOf="@+id/button"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toBottomOf="@+id/textView2"
		app:layout_constraintVertical_bias="0.508" />

	<!-- Button to display next random string -->
	<Button
		android:id="@+id/button"
		android:layout_width="0dp"
		android:layout_height="wrap_content"
		android:layout_margin="@android:dimen/notification_large_icon_height"
		android:background="#4CAF50"
		android:text="@string/buttonText"
		android:textAllCaps="true"
		android:textColor="@android:color/background_light"
		android:textSize="20sp"
		android:textStyle="bold"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintLeft_toLeftOf="parent"
		app:layout_constraintRight_toRightOf="parent"
		app:layout_constraintTop_toTopOf="parent"
		app:layout_constraintVertical_bias="0.79" />

	<!-- Progress Bar to be displayed before displaying next string -->
	<ProgressBar
		android:id="@+id/progressBar"
		style="?android:attr/progressBarStyleLarge"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:visibility="gone"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintLeft_toLeftOf="parent"
		app:layout_constraintRight_toRightOf="parent"
		app:layout_constraintTop_toTopOf="parent" />

	<ImageView
		android:id="@+id/imageView"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		app:layout_constraintBottom_toBottomOf="parent"
		app:layout_constraintEnd_toEndOf="parent"
		app:layout_constraintStart_toStartOf="parent"
		app:layout_constraintTop_toBottomOf="@+id/button"
		app:layout_constraintVertical_bias="1.0"
		app:srcCompat="@drawable/banner" />

</androidx.constraintlayout.widget.ConstraintLayout>

4: Defining the Contract Interface file for the Model, View, and Presenter

There is a need for an interface to establish communication between View-Presenter and Presenter-Model. This interface class contains all abstract methods, defined later in the View, Model, and Presenter class.

public interface Contract {
	interface View {
		// method to display progress bar
		// when next random course details
		// is being fetched
		void showProgress();

		// method to hide progress bar
		// when next random course details
		// is being fetched
		void hideProgress();

		// method to set random
		// text on the TextView
		void setString(String string);
	}

	interface Model {

		// nested interface to be
		interface OnFinishedListener {
			// function to be called
			// once the Handler of Model class
			// completes its execution
			void onFinished(String string);
		}

		void getNextCourse(Contract.Model.OnFinishedListener onFinishedListener);
	}

	interface Presenter {

		// method to be called when
		// the button is clicked
		void onButtonClick();

		// method to destroy
		// lifecycle of MainActivity
		void onDestroy();
	}
}

5: Creating the Model class

import android.os.Handler;

import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Model implements Contract.Model {

	// array list of strings from which
	// random strings will be selected
	// to display in the activity
	private List<String> arrayList = Arrays.asList(
			"DSA Self Paced: Master the basics of Data Structures and Algorithms to solve complex problems efficiently. ",
			"Placement 100: This course will guide you for placement with theory,lecture videos, weekly assignments " +
					"contests and doubt assistance.",
			"Amazon SDE Test Series: Test your skill & give the final touch to your preparation before applying for " +
					"product based against like Amazon, Microsoft, etc.",
			"Complete Interview Preparation: Cover all the important concepts and topics required for the interviews. " +
					"Get placement ready before the interviews begin",
			"Low Level Design for SDE 1 Interview: Learn Object-oriented Analysis and Design to prepare for " +
					"SDE 1 Interviews in top companies"
	);

	@Override
	// this method will invoke when
	// user clicks on the button
	// and it will take a delay of
	// 1200 milliseconds to display next course detail
	public void getNextCourse(final OnFinishedListener listener) {
		new Handler().postDelayed(new Runnable() {
			@Override
			public void run() {
				listener.onFinished(getRandomString());
			}
		}, 1200);
	}

	// method to select random
	// string from the list of strings
	private String getRandomString() {
		Random random = new Random();
		int index = random.nextInt(arrayList.size());
		return arrayList.get(index);
	}
}

6: Creating the Presenter class

public class Presenter implements Contract.Presenter, Contract.Model.OnFinishedListener {

	// creating object of View Interface
	private Contract.View mainView;

	// creating object of Model Interface
	private Contract.Model model;

	// instantiating the objects of View and Model Interface
	public Presenter(Contract.View mainView, Contract.Model model) {
		this.mainView = mainView;
		this.model = model;
	}

	@Override
	// operations to be performed
	// on button click
	public void onButtonClick() {
		if (mainView != null) {
			mainView.showProgress();
		}
		model.getNextCourse(this);
	}

	@Override
	public void onDestroy() {
		mainView = null;
	}

	@Override
	// method to return the string
	// which will be displayed in the
	// Course Detail TextView
	public void onFinished(String string) {
		if (mainView != null) {
			mainView.setString(string);
			mainView.hideProgress();
		}
	}
}

7: Define functionalities of View in the MainActivity file

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import static android.view.View.GONE;

public class MainActivity extends AppCompatActivity implements Contract.View {

	// creating object of TextView class
	private TextView textView;

	// creating object of Button class
	private Button button;

	// creating object of ProgressBar class
	private ProgressBar progressBar;

	// creating object of Presenter interface in Contract
	Contract.Presenter presenter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// assigning ID of the TextView
		textView = findViewById(R.id.textView);

		// assigning ID of the Button
		button = findViewById(R.id.button);

		// assigning ID of the ProgressBar
		progressBar = findViewById(R.id.progressBar);

		// instantiating object of Presenter Interface
		presenter = new Presenter(this, new Model());

		// operations to be performed when
		// user clicks the button
		button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				presenter.onButtonClick();
			}
		});
	}

	@Override
	protected void onResume() {
		super.onResume();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		presenter.onDestroy();
	}

	@Override
	// method to display the Course Detail TextView
	public void showProgress() {
		progressBar.setVisibility(View.VISIBLE);
		textView.setVisibility(View.INVISIBLE);
	}

	@Override
	// method to hide the Course Detail TextView
	public void hideProgress() {
		progressBar.setVisibility(GONE);
		textView.setVisibility(View.VISIBLE);
	}

	@Override
	// method to set random string
	// in the Course Detail TextView
	public void setString(String string) {
		textView.setText(string);
	}
}

MVVM (Model View ViewModel)

Model View View Model is an architecture pattern that separates the code for Android applications into 3 layers which are as follows −

  • Model − The model is responsible for storing the data used within an Android application. This layer is also used for the abstraction of data sources.
  • View − The view layer in MVVM can help to get the actions performed by the user within an Android application. This layer will also inform ViewModel about the user interaction with the View.
  • ViewModel − ViewModel is used to get the data from the Model and display it to the user through the View Layer.

Advantages of using MVVM Pattern

  • MVVM makes it easy to maintain the code.
  • As MVVM separates the different layers of the code which makes it easy to test the code.

Example Code

1: To enable DataBinding in the android application, the below-given codes need to be added to the app’s build.gradle(build.gradle (:app)) file:

Enable DataBinding:

android {

   dataBinding {

 enabled = true

      }

}

2: Add lifecycle dependency:
implementation ‘android.arch.lifecycle:extensions:1.1.1’
3: Create a new project
4: Modify String.xml file

<resources>
	<string name="app_name">MVVM Architecture</string>
	<string name="heading">MVVM Architecture Pattern</string>
	<string name="email_hint">Enter your Email ID</string>
	<string name="password_hint">Enter your password</string>
	<string name="button_text">Login</string>
</resources>

5: Creating the Model class
import androidx.annotation.Nullable;

public class Model {


	@Nullable
	String email,password;


	// constructor to initialize
	// the variables
	public Model(String email, String password){
		this.email = email;
		this.password = password;
	}


	// getter and setter methods
	// for email variable
	@Nullable
	public String getEmail() {
		return email;
	}


	public void setEmail(@Nullable String email) {
		this.email = email;
	}


	// getter and setter methods
	// for password variable
	@Nullable
	public String getPassword() {
		return password;
	}


	public void setPassword(@Nullable String password) {
		this.password = password;
	}


}

6: activity_main.xml file

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="https://schemas.android.com/apk/res/android"
	xmlns:app="https://schemas.android.com/apk/res-auto"
	xmlns:bind="https://schemas.android.com/tools">


	<!-- binding object of ViewModel to the XML layout -->
	<data>
		<variable
			name="viewModel"
			type="com.example.mvvmarchitecture.AppViewModel" />
	</data>


	<!-- Provided Linear layout for the activity components -->
	<LinearLayout
		android:layout_width="match_parent"
		android:layout_height="match_parent"
		android:layout_gravity="center"
		android:layout_margin="8dp"
		android:background="#168BC34A"
		android:orientation="vertical">


		<!-- TextView for the heading of the activity -->
		<TextView
			android:id="@+id/textView"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:text="@string/heading"
			android:textAlignment="center"
			android:textColor="@android:color/holo_green_dark"
			android:textSize="36sp"
			android:textStyle="bold" />


		<!-- EditText field for the Email -->
		<EditText
			android:id="@+id/inEmail"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginStart="10dp"
			android:layout_marginTop="60dp"
			android:layout_marginEnd="10dp"
			android:layout_marginBottom="20dp"
			android:hint="@string/email_hint"
			android:inputType="textEmailAddress"
			android:padding="8dp"
			android:text="@={viewModel.userEmail}" />


		<!-- EditText field for the password -->
		<EditText
			android:id="@+id/inPassword"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginStart="10dp"
			android:layout_marginEnd="10dp"
			android:hint="@string/password_hint"
			android:inputType="textPassword"
			android:padding="8dp"
			android:text="@={viewModel.userPassword}" />


		<!-- Login Button of the activity -->
		<Button
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginStart="20dp"
			android:layout_marginTop="60dp"
			android:layout_marginEnd="20dp"
			android:background="#4CAF50"
			android:fontFamily="@font/roboto"
			android:onClick="@{()-> viewModel.onButtonClicked()}"
			android:text="@string/button_text"
			android:textColor="@android:color/background_light"
			android:textSize="30sp"
			android:textStyle="bold"
			bind:toastMessage="@{viewModel.toastMessage}" />


		<ImageView
			android:id="@+id/imageView"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:layout_marginTop="135dp"
			app:srcCompat="@drawable/banner" />


	</LinearLayout>
</layout>

7: Creating the ViewModel class

import android.text.TextUtils;
import android.util.Patterns;
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;


public class AppViewModel extends BaseObservable {


	// creating object of Model class
	private Model model;


	// string variables for
	// toast messages
	private String successMessage = "Login successful";
	private String errorMessage = "Email or Password is not valid";


	@Bindable
	// string variable for
	// toast message
	private String toastMessage = null;


	// getter and setter methods
	// for toast message
	public String getToastMessage() {
		return toastMessage;
	}


	private void setToastMessage(String toastMessage) {
		this.toastMessage = toastMessage;
		notifyPropertyChanged(BR.toastMessage);
	}


	// getter and setter methods
	// for email variable
	@Bindable
	public String getUserEmail() {
		return model.getEmail();
	}


	public void setUserEmail(String email) {
		model.setEmail(email);
		notifyPropertyChanged(BR.userEmail);
	}


	// getter and setter methods
	// for password variable
	@Bindable
	public String getUserPassword() {
		return model.getPassword();
	}


	public void setUserPassword(String password) {
		model.setPassword(password);
		notifyPropertyChanged(BR.userPassword);
	}


	// constructor of ViewModel class
	public AppViewModel() {


		// instantiating object of
		// model class
		model = new Model("","");
	}


	// actions to be performed
	// when user clicks
	// the LOGIN button
	public void onButtonClicked() {
		if (isValid())
			setToastMessage(successMessage);
		else
			setToastMessage(errorMessage);
	}


	// method to keep a check
	// that variable fields must
	// not be kept empty by user
	public boolean isValid() {
		return !TextUtils.isEmpty(getUserEmail()) && Patterns.EMAIL_ADDRESS.matcher(getUserEmail()).matches()
				&& getUserPassword().length() > 5;
	}
}

8: MainActivity file

import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.BindingAdapter;
import androidx.databinding.DataBindingUtil;
import com.example.mvvmarchitecture.databinding.ActivityMainBinding;


public class MainActivity extends AppCompatActivity {


	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);


		// ViewModel updates the Model
		// after observing changes in the View


		// model will also update the view
		// via the ViewModel
		ActivityMainBinding activityMainBinding
			= DataBindingUtil.setContentView(
				this, R.layout.activity_main);
		activityMainBinding.setViewModel(
			new AppViewModel());
		activityMainBinding.executePendingBindings();
	}
}


// any change in toastMessage attribute
// defined on the Button with bind prefix
// invokes this method
@BindingAdapter({ "toastMessage" })
public static void runMe(View view, String message)
{
if (message != null)
	Toast
	.makeText(view.getContext(), message,
			Toast.LENGTH_SHORT)
	.show();
}

Recent Blogs


Posted

in

,

by

Tags:

To Know Us Better

Browse through our work.

Explore The Technology Used

Learn about the cutting-edge technology and techniques we use to create innovative software solutions.