Você está na página 1de 13

Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?

comp=29924

www.devmedia.com.br
[versão para impressão]
Link original: http://www.devmedia.com.br/articles/viewcomp.asp?comp=29924

Hoje em dia a demanda de desenvolvimento de aplicativos móveis é muito alta.


Para ser competitivo, um aplicativo móvel deve ser eficaz em termos de custos e
ser de boa qualidade.

A escolha da arquitetura é importante para garantir a qualidade da aplicação a


longo tempo e para reduzir o tempo de desenvolvimento.

O desenvolvimento iOS é baseado no Model-View-Controller e é bem estruturado.


O sistema Android não requer qualquer modelo: a escolha da arquitetura e a
qualidade da aplicação dependem muito da experiência do desenvolvedor.

Soluções heterogêneas desaceleram o desenvolvedor, enquanto o padrão de


design conhecido não só poderia aumentar o tempo de desenvolvimento, mas
melhorar a capacidade de manutenção, extensibilidade e o desempenho da
aplicação.

MVC (Model-View-Controller) é um padrão de projeto de software que separa a

1 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

interface do usuário (View) e das regras de negócio e dados (Model) usando um


mediador (Controller) para conectar o modelo à view.

O principal benefício do MVC para nós é a separação de interesses. Cada parte


do MVC cuida de seu próprio trabalho: a view cuida da interface com o usuário, o
modelo se encarrega dos dados, e o controlador envia mensagens entre os dois.

O controlador fornece os dados do modelo para a view se ligar a interface do


usuário. Quaisquer alterações ao controlador são transparentes para a view e as
mudanças de interface do usuário não afetarão a lógica de negócios e vice-versa.

Os padrões de design ajudam a impor uma estrutura sobre os desenvolvedores


para que o código se torne mais controlado e menos propenso a cair em desuso.
A separação do MVC de interesses torna muito mais fácil para adicionar unidades
de testes.

O Android já utiliza um padrão MVC com os arquivos XML agindo como a view.
Contudo, isto não nos fornece quaisquer possibilidades reais de separação de
interesses.

Para demonstrar o MVC (Model-View-Controller) framework para Android,


criaremos um exemplo de tela que contém o logo da DEVMEDIA, conforme
mostrado na Figura 1, e outra tela que contém um campo para digitar
determinada tarefa a realizar e um botão de Nova Tarefa. Ao pressionar o botão, o
valor da tarefa será incluído no banco de dados e na lista de tarefas a realizar. Ao
selecionar algum item da lista, o mesmo será excluído do banco de dados,
conforme mostrado na Figura 2.

2 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

Figura 1. Tela Splash

Figura 2. Tela Principal

A seguir, podemos visualizar a classe que atua como Model da aplicação,


conforme mostrado na Listagem 1.

Nota: O Android tem integração com o SQLite, um leve e poderoso banco de


dados, permitindo que você utilize banco de dados normalmente e sua aplicação.
Um banco de dados é visível somente à aplicação que o criou. A classe
SQLiteHelper encapsula toda a lógica de criação de um banco. Os métodos
onCreate e onUpgrade são chamados automaticamente pelo Android quando o
banco precisa ser criado pela primeira vez ou ao ser atualizado devido a uma nova
versão.

Listagem 1. mvcModel.java

package com.devmedia.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 = "tarefas_db";
private static final String TABLE_NAME = "tarefa";

3 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

private static final int DB_VERSION = 1;


private static final String DB_CREATE_QUERY = "CREATE TABLE " +
mvcModel.TABLE_NAME + " (id integer primary key autoincrement,
titulo 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 addTarefa(ContentValues data)


{
this.database.insert(mvcModel.TABLE_NAME, null, data);
}

public void deleteTarefa(final String field_params)


{
this.database.delete(mvcModel.TABLE_NAME, field_params, null);
}

public Cursor loadAllTarefas()


{
Log.d(mvcView.APP_TAG, "loadAllTarefas()");

final Cursor c = this.database.query(mvcModel.TABLE_NAME,

4 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

new String[] { "titulo" }, null, null, null, null, null);

return c;
}
}

A seguir podemos visualizar a classe que atua como View da aplicação, conforme
mostrado na Listagem 2.

Listagem 2. mvcView.java

import android.widget.TextView;

import com.devmedia.mvc.R;

public class mvcView extends Activity


{
public static final String APP_TAG = "com.devmedia.mvc";

private ListView lvTarefa;


private Button btNovaTarefa;
private EditText etNovaTarefa;

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.lvTarefa = (ListView) this.findViewById(R.id.lvTarefa);


this.btNovaTarefa = (Button) this.findViewById(R.id.btNovaTarefa);
this.etNovaTarefa = (EditText)
this.findViewById(R.id.etNovaTarefa);

this.btNovaTarefa.setOnClickListener(this.handleNovaTarefaEvent);

this.populaTarefas();
}

private void populaTarefas()


{

5 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

final List<String> tarefas = this.controller.getTarefas();

Log.d(mvcView.APP_TAG, String.format("%d tarefas encontradas ",


tarefas.size()));

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

this.lvTarefa.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("tarefa id: %d
e posição: %d", id, position));

final TextView v = (TextView) view;

mvcView.this.controller.deleteTarefa
(v.getText().toString());

mvcView.this.populaTarefas();
}
});
}

private final OnClickListener handleNovaTarefaEvent =


new OnClickListener()
{
@Override
public void onClick(final View view)
{
Log.d(APP_TAG, "botão nova tarefa acionado");

mvcView.this.controller.addTarefa(mvcView.this
.etNovaTarefa.getText().toString());

mvcView.this.populaTarefas();
}
};

@Override
protected void onStart()

6 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

{
super.onStart();
}

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

O Controller liga a interface do usuário com os dados, mas também cria uma
camada de separação entre o Model e a View. Esta interface entre as duas
camadas fornece uma estrutura para o código expandir.

A seguir podemos visualizar a classe que atua como Controller da aplicação,


conforme mostrado na Listagem 3.

Listagem 3. mvcController.java

package com.devmedia.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> tarefas;

public mvcController(Context app_context)


{
tarefas = new ArrayList<String>();
model = new mvcModel(app_context);
}

public void addTarefa(final String titulo)


{
final ContentValues data = new ContentValues();
data.put("titulo", titulo);
model.addTarefa(data);
}

7 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

public void deleteTarefa(final String titulo)


{
model.deleteTarefa("titulo='" + titulo + "'");
}

public void deleteTarefa(final long id)


{
model.deleteTarefa("id='" + id + "'");
}

public void deleteAllTarefa()


{
model.deleteTarefa(null);
}

public List<String> getTarefas()


{
Cursor c = model.loadAllTarefas();
tarefas.clear();

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

while (c.isAfterLast() == false)


{
tarefas.add(c.getString(0));
c.moveToNext();
}

c.close();
}

return tarefas;
}
}

Uma tela splash screen deve permanecer aberta por determinado tempo para que
a aplicação consiga realizar algum processamento inicial. Enquanto isso, o usuário
pode ficar observando uma imagem ou mensagem na tela.

A seguir podemos visualizar a classe que atua como tela Splash da aplicação,
conforme mostrado na Listagem 4.

8 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

Listagem 4. mvcSplash.java

package com.devmedia.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.devmedia.mvc.mvcView");
startActivity(intent);
}
}
};

timer.start();
}
}

O arquivo AndroidManifest.xml é a base de uma aplicação Android. Ele é


obrigatório e deve ficar na pasta raiz do projeto, contendo todas as configurações
necessárias para executar a aplicação.

9 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

A seguir podemos visualizar o arquivo AndroidManifest, conforme mostrado na


Listagem 5.

Listagem 5. AndroidManifest.xml

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


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.devmedia.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.devmedia.mvc.mvcView">
<intent-filter>
<action android:name="com.devmedia.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>

O Android é bastante flexível em relação à criação da interface gráfica e permite


que a tela seja criada em XML ou diretamente pelo código-fonte utilizando a API
Java. Separando a criação da tela em um arquivo XML, seu código fica mais
limpo. A seguir, podemos visualizar os arquivos de layout de tela, conforme
mostrado nas Listagens 6 e 7.

Listagem 6. ui_main.xml

10 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

<?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/lvTarefa"
android:orientation="horizontal" >

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

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

<ListView
android:id="@+id/lvTarefa"
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"?>

11 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

<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>

O arquivo strings.xml contém as mensagens da aplicação para organizar os textos


em um único arquivo centralizado, o que é uma boa prática de programação.
Desta forma, podemos facilmente traduzir este arquivo para diversos idiomas e
tornar nossa aplicação bastante internacionalizável. A seguir, podemos visualizar o
arquivo strings.xml, conforme mostrado na Listagem 8.

Listagem 8: strings.xml

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


<resources>

<string name="app_name">Criando um MVC(Model-View-Controller)


framework para Android</string>
<string name="action_settings">Settings</string>
<string name="add_button_name">Nova Tarefa</string>

</resources>

Um dos problemas fundamentais com todos os tipos de software pode ser


resumido no conceito de entropia, que sugere que o código ordenado
naturalmente se torna desordenado ao longo do tempo. Ou em outras palavras,
não importa o quão duro você tente, seu código irá gradualmente ir de um estado
organizado para um estado desorganizado em que também é conhecido como
altamente acoplado.

Até a próxima!

Um abraço.

Referências:

12 de 13 23/11/2017 12:04
Android MVC: Criando um Framework Model-View-Controller para ... http://www.devmedia.com.br/articles/viewcomp_forprint.asp?comp=29924

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

http://www.sqlite.org/

por Jorge Luiz


Especialista em aplicações mobile

13 de 13 23/11/2017 12:04

Você também pode gostar