Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Android MVC: Creating a Model-View-Controller Framework for Android

See in this article how to create an MVC framework (Model-View-Controller) for Android, thereby improving the development on this platform.

Today, mobile application development demand is very high. To be competitive, a mobile application should be effective in terms of cost and be of good quality.

The architecturechoiceis important to ensure the quality of implementation long time and reduce development time.

iOS development is based on the Model-View-Controller and is well structured. The Android system does not require any model: the architecturechoiceand application quality depends largely on the developer experience.

Heterogeneous solutions decelerate the developer, while the standard of known design not only could increase development time, but improve maintainability, extensibility and application performance.

MVC (Model-View-Controller) is a standard software project that separates the user interface (View) and the business rules and data (Model) using a mediator (Controller) to connect the model to the view.

The main benefit for us is the MVC separation of concerns. Each part of the MVC takes care of its own work: the view takes care of the user interface, the model takes care of the data, and the controller sends messages between both of them.

The controller provides the data model to view connect the user interface. Any changes to the controller are transparent to view and UI changes will not affect the business logic and vice versa.

Design patterns help to impose a structure on developers so that the code becomes more controlled and less prone to fall into disuse. The separation of the interests of MVC makes it much easier to add unit tests.

Android already uses an MVC pattern with XML files acting as a view. However, this does not give us any real possibilities of separation of concerns.

To demonstrate the MVC (Model-View-Controller) framework for Android, we will create an example of the screen that contains the logo of MrBool, as shown in Figure 1, and another screen that contains a field to enter specific task to perform and a Button New Task. When you press the button, the task of value will be included in the database and the list of tasks to perform. When you select a list item, it will be deleted from the database, as shown in Figure 2.


Figure 1. Splash Screen


Figure 2.Main Screen

Below, we can see the class that acts as application Model, as shown in Listing 1.

Note: The Android has integration with SQLite, a lightweight and powerful database, allowing you to use database normally and its application. A database is only visible to the application that created it. The SQLiteHelper class encapsulates all the creation of a database logic. The onCreate and onUpgrade methods are called automatically by Android when the database needs to be created for the first time or to be updated due to a new version.

Listing 1. mvcModel.java
package com.mrbool.mvc;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

final class MVCModel
{
  private static final String DB_NAME = "tasks_db";
  private static final String TABLE_NAME = "task";
  private static final int DB_VERSION = 1;
  private static final String DB_CREATE_QUERY = "CREATE TABLE " +
	MVCModel.TABLE_NAME + " (id integer primary key autoincrement, 
	title text not null);";

  private final SQLiteDatabase database;
  
  private final SQLiteOpenHelper helper;

  public MVCModel(final Context ctx)
  {
	  this.helper = new SQLiteOpenHelper(ctx, MVCModel.DB_NAME,
	   null, MVCModel.DB_VERSION)
	  {
		  @Override
		  public void onCreate(final SQLiteDatabase db)
		  {
			  db.execSQL(MVCModel.DB_CREATE_QUERY);
		  }

		  @Override
		  public void onUpgrade(final SQLiteDatabase db, 
		   final int oldVersion, final int newVersion)
		  {
			  db.execSQL("DROP TABLE IF EXISTS " + MVCModel.TABLE_NAME);
			  this.onCreate(db);
		  }
	  };

	  this.database = this.helper.getWritableDatabase();
  }

  public void addTask(ContentValues data)
  {
	  this.database.insert(MVCModel.TABLE_NAME, null, data);
  }

  public void deleteTask(final String field_params)
  {
	  this.database.delete(MVCModel.TABLE_NAME, field_params, null);
  }

  public Cursor loadAllTasks()
  {
	  Log.d(mvcView.APP_TAG, "loadAllTasks()");

	  final Cursor c = this.database.query(MVCModel.TABLE_NAME, 
	   new String[] { "title" }, null, null, null, null, null);

	  return c;
  }}


Below we can see the class that acts as application of View, as shown in Listing 2.

Listing 2. MVCView.java
import android.widget.TextView;

import com.mrbool.mvc.R;

public class MVCView extends Activity
{
  public static final String APP_TAG = "com.mrbool.mvc";

  private ListView lvTask;
  private Button btNewTask;
  private EditText etNewTask;

  private mvcController controller;

  @Override
  public void onCreate(final Bundle bundle)
  {
	  super.onCreate(bundle);

	  this.setContentView(R.layout.ui_main);

	  this.controller = new mvcController(this);
	  
	  this.lvTask = (ListView) this.findViewById(R.id.lvTask);
	  this.btNewTask = (Button) this.findViewById(R.id.btNewTask);
	  this.etNewTask = (EditText) 
	   this.findViewById(R.id.etNewTask);
	  
	  this.btNewTask.setOnClickListener(this.handleNewTaskEvent);

	  this.populateTasks();
  }

  private void populateTasks()
  {
	  final List<String> tasks = this.controller.getTasks();

	  Log.d(MVCView.APP_TAG, String.format("%d found tasks ", 
			 tasks.size()));

	  this.lvTask.setAdapter(new ArrayAdapter<String>
	  (this, android.R.layout.simple_list_item_1, 
		tasks.toArray(new String[] {})));

	  this.lvTask.setOnItemClickListener(new OnItemClickListener()
	  {
		  @Override
		  public void onItemClick(final AdapterView<?> parent, 
		   final View view, final int position, final long id)
		  {
			  Log.d(MVCView.APP_TAG, String.format("task id: %d 
			   and position: %d", id, position));

			  final TextView v = (TextView) view;
			  
			  MVCView.this.controller.deleteTask
			   (v.getText().toString());
			  
			  
			  MVCView.this.populateTasks();
		  }
	  });
  }
  
  private final OnClickListener handleNewTaskEvent = 
   new OnClickListener()
  {
	  @Override
	  public void onClick(final View view)
	  {
		  Log.d(APP_TAG, "New Task button added");

		   MVCView.this.controller.addTask(MVCView.this
		   .etNewTask.getText().toString());

		  MVCView.this.populateTasks();
	  }
  };


  @Override
  protected void onStart()
  {
	  super.onStart();
  }
  
  @Override
  protected void onStop()
  {
	  super.onStop();
  }}


The controller connects the user interface to the data, but also creates a layer of separation between the Model and the View. This interface between the two layers provides a structure to expand the code.

The following can view the application class that acts as the controller, as shown in Listing 3.

Listing 3. mvcController.java

package com.mrbool.MVC;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;

import java.util.ArrayList;
import java.util.List;

public class MVCController
{
  private MVCModel model;
  private List<String> tasks;

  public MVCController(Context app_context)
  {
	  tasks = new ArrayList<String>();
	  model = new MVCModel(app_context);
  }

  public void addTask(final String title)
  {
	  final ContentValues data = new ContentValues();
	  data.put("title", title);
	  model.addTask(data);
  }

  public void deleteTask(final String title)
  {
	  model.deleteTask("title='" + title + "'");
  }

  public void deleteTask(final long id)
  {
	  model.deleteTask("id='" + id + "'");
  }

  public void deleteAllTask()
  {
	  model.deleteTask(null);
  }

  public List<String> getTasks()
  {
	  Cursor c = model.loadAllTasks();
	  tasks.clear();

	  if (c != null)
	  {
		  c.moveToFirst();

		  while (c.isAfterLast() == false)
		  {
			  tasks.add(c.getString(0));
			  c.moveToNext();
		  }
		  
		  c.close();
	  }

	  return tasks;
  }} 


A splash screen display must remain open for a specified time so that the application can perform some initial processing. Meanwhile, the user may be watching an image or message on the screen.

Below we can see the class that acts as implementation of Splash screen, as shown in Listing 4.

Listing 4. mvcSplash.java
package com.mrbool.MVC;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;

public class MVCSplash extends Activity
{
  public void onCreate(Bundle savedInstanceState)
  {
	  super.onCreate(savedInstanceState);

	  setContentView(R.layout.ui_splash);
	  
	  Thread timer = new Thread()
	  {
		  public void run()
		  {
			  try
			  {
				  sleep(1000);
			  }
			  catch (InterruptedException e)
			  {
				  e.printStackTrace();
			  }
			  finally
			  {
				  Intent intent = new Intent
				   ("com.mrbool.MVC.MVCView");
				  startActivity(intent);
			  }
		  }
	  };
	  
	  timer.start();
  }}


The AndroidManifest.xml file is the basis of an Android application. It is required and must be in the root folder of the project, containing all the settings needed to run the application.

Then we can view the AndroidManifest file, as shown in Listing 5.

Listing 5. AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.mrbool.mvc"
  android:versionCode="1"
  android:versionName="1.0" >
  <uses-sdk
	  android:minSdkVersion="8"
	  android:targetSdkVersion="19" />
  <application
	  android:allowBackup="true"
	  android:icon="@drawable/ic_launcher"
	  android:label="@string/app_name"
	  android:theme="@style/AppTheme" >
	  <activity android:label="@string/app_name"
		  android:name="com.mrbool.mvc.MVCView">
		  <intent-filter>
			  <action android:name="com.mrbool.mvc.MVCView" />
			  <category android:name=
				 "android.intent.category.DEFAULT" />
		  </intent-filter>
	  </activity>
	  <activity android:name=".MVCSplash">
		  <intent-filter>
			  <action android:name="android.intent.action.MAIN"/>
			  <category android:name=
			   "android.intent.category.LAUNCHER"/>
		  </intent-filter>
	  </activity>
  </application>
</manifest>


Android is very flexible in relation to the creation of the graphical interface and allows the screen to be created in XML or directly from source code using the Java API. Separating the screen creation in an XML file, your code is cleaner. Next, we can view the screen layout files, as shown in Listings 6 and 7.

Listing 6. ui_main.xml
<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
  
  android:id="@+id/widget31"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" >

  <TableRow
	  android:id="@+id/row"
	  android:layout_width="fill_parent"
	  android:layout_height="wrap_content"
	  android:layout_alignParentLeft="true"
	  android:layout_below="@+id/lvTask"
	  android:orientation="horizontal" >

	  <EditText
		  android:id="@+id/etNewTask"
		  android:layout_width="200dp"
		  android:layout_height="wrap_content"
		  android:text=""
		  android:textSize="18sp" >
	  </EditText>

	  <Button
		  android:id="@+id/btNewTask"
		  android:layout_width="wrap_content"
		  android:layout_height="wrap_content"
		  android:text="@string/add_button_name" >
	  </Button>
  </TableRow>

  <ListView
	  android:id="@+id/lvTask"
	  android:layout_width="fill_parent"
	  android:layout_height="wrap_content"
	  android:layout_alignParentLeft="true"
	  android:layout_alignParentTop="true" >
  </ListView>
</RelativeLayout>


Listagem 7.ui_splash.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
			android:orientation="vertical"
			android:layout_width="fill_parent"
			android:layout_height="fill_parent">

	 <ImageView
		  android:layout_width="fill_parent"
		  android:layout_height="fill_parent"
		  android:id="@+id/placekitten"
		  android:src="@drawable/splash"/>
</LinearLayout>

The strings.xml file contains the application messages to organize the texts in one central file, which is a good programming practice. Thus, we can easily translate this file into several languages and make our very internationalizable application. Next, we can view the strings.xml file, as shown in Listing 8.

Listing 8: strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

  <string name="app_name">Creating an MVC (Model-View-Controller)   
	 framework for Android</string>
  <string name="action_settings">Settings</string>
  <string name="add_button_name">New Task</string>
  
</resources>

A fundamental problem with all types of software can be summarized in the concept of entropy, suggesting that the code becomes untidy ordered naturally over time. Or in other words, no matter how hard you try, your code will gradually go from an organized state to a disorganized state in which is also known as highly coupled.

Until next time!

References

http://developer.android.com/guide/index.html

http://www.sqlite.org/



Julio is a System analyst and enthusiast of Information Technology. He is currently a developer at iFactory Solutions company, working in the development of strategic systems, is also a JAVA instructor. He has knowledge and experi...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login