En esta entrada, voy a explicar a grandes rasgos, cómo montar una buena estructura de directorios y clases para una aplicación desarrollada con Android.

Como bien sabréis, el modelo más clásico para desarrollar aplicaciones de todo tipo (salvo casos concretos), es el MVC. No me voy a entretener explicando que es, así que quien tenga interés en conocerlo más a fondo, que visite este enlace.

A grandes rasgos, tenemos:

* M: [Modelo]: Donde definiremos todos los objetos que existirán en nuestra aplicación

* V:  [Vista] Donde tendremos toda la parte visual (esencialmente, Layouts, Activities…)

* C:  [Controlador] Aquí programaremos todo lo que son Managers.

Empezaremos creando una estructura de directorios similar a esta (a partir de ahora, es la que usaremos para ir trabajando sobre el contenido de este blog).

Y aquí tenemos la estructura más simple (pero ordenada) de una aplicación Android

¿Qué tenemos aquí?

En el directorio “activity“, iremos incluyendo las activities que vayamos desarrollando. He dejado una, AndroidToastE1Activity.java aislada de la estructura. Es una manía mía pero podéis obviarla. Normalmente, uso esa Activity a modo de testeo de los resultados que veríamos en una Activity en concreto. Así, no tengo que ir siguiendo siempre el flujo de ejecución para llegar a un caso concreto.

Seguidamente, tenemos el directorio “controller“. Aquí definiremos, por un lado la Interfaz de la clase y por otro su implementación. El controller, deberá ser un Singleton. ¿Porqué Singleton?, pues porque el controller instanciará todos los managers y hará el trabajo sucio de recoger el contexto de las activities por nosotros.

CREACIÓN DEL CONTROLLER

Ahora, vamos a ver, cómo crear este “Controller” que de ahora en adelante, usaremos para nuestras aplicaciones de Android.

Crearemos una interfaz ControllerInterface.java y la pondremos en el package com.danielsanteugini.com.androidtoast.controller y una clase, que implementará este Controller, llamada Controller.java

Código fuente para ControllerInterface.java:


package com.danielsanteugini.androidtoast.controller

public interface ControllerInterface {

   public void setActivity(Activity activity);

}

Seguidamente, implementaremos la clase que requiere de la interfaz ControllerInterface. El código es un singleton puro, así que explicaremos un poco por encima, qué hace el código.


package com.danielsanteugini.androidtoast.controller.impl;

import android.app.Activity;
import android.util.Log;

import com.doubleyou.evax.epc.controller.ControllerInterface;

public class Controller implements ControllerInterface {
	private static Controller instance;
	private Activity activity;

        // Metodo estatico que nos permite obtener
        // la instacia actual del controller

	public static synchronized Controller getInstance() {
             // Si nunca se ha instanciado el controller
             // lo hacemos ahora, llamando al constructor privado
             if (instance == null) {
                 instance = new Controller();
             }
             // Devolvemos si o si la instancia del controller.
             // Si ya existía, devolveremos la instancia que habíamos
             // creado ya. Sino, la que hemos creado en el código
             // del if.
             return instance;
        }

	private Controller(){
	     // Constructor privado
	}

        // Metodo que tenemos que llamar desde la activity que vaya
        // a usar el controller.
        // Se hará de la siguiente forma: setActivity(this)
	public void setActivity(Activity activity) {
		Log.d(this.getClass().getName(),"Activity "+activity.getClass().getName()+" setted");
		this.activity = activity;
	}
}

Nota: Mientras escribía esta entrada, me he dado cuenta de que para ser más puristas, deberíamos modificar un poco la implementación del Controller. Lo ideal, sería que cada vez que nos pidan la instancia del Controller, miremos si la “Activity” privada está definida. Es decir, si nos han ejecutado el método setActivity. En caso de que no esté definida y además, ya tengamos definida la instancia del controller (es decir, ya nos han llamado alguna vez), lanzaremos una excepción para avisar de que es obligatorio setear la Activity.

En la siguiente entrada, explicaré cómo crear nuestro primer Manager (muy simple).

Infame AndroidManifest.xml

Publicado: noviembre 11, 2011 en Uncategorized

Bienvenidos al mundo del infame AndroidManifest.xml

AndroidManifest.xml es a Android lo que web.xml es a Java. El descriptor de la aplicación que vamos a ejecutar.

Siguiendo los pasos de la entrega anterior, la de Conceptos Básicos, recuperamos el proyecto y hacemos doble click en el fichero AndroidManifest.xml. Honestamente, os recomiendo que lo visualicéis como un XML, no uséis la interfaz simplificada. Aquí tenemos el AndroidManifest.xml más simple posible:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.danielsanteugini.androidtoast"
     android:versionCode="1"
     android:versionName="1.0">
     <uses-sdk android:minSdkVersion="8" />

     <application android:icon="@drawable/icon" android:label="@string/app_name">
          <activity android:name=".AndroidToastE1Activity"
                    android:label="@string/app_name">
               <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
               </intent-filter>
          </activity>

     </application>
</manifest>

Veamos ahora, qué significa este XML.

Por un lado, tenemos el nombre del package (lo habíamos definido en el Wizard), el SDK que va a usar la aplicación. Aquí estamos definiendo también, la versión mínima del SDK necesaria. En este caso es la 8. (Android 2.2). Si necesitáis ver la correspondencia entre versiones, aquí la tenéis:

Distribución API
4.0 Icrecream Sandwitch 14-15
3.x.x Honeycomb 11-13
2.3.x Gingerbread 9-10
2.2 Froyo 8
2.1 Eclair 7
1.6 Donut 4
1.0 Cupcake 3

El bloque definido por aplication, contiene todas las activities que van a usarse. Es importante tener en cuenta, que todas las clases que hereden de Activity y queramos que realmente sean usadas como Activities…deben estar definidas aquí.

<activity android:name=".AndroidToastE1Activity"
          android:label="@string/app_name">
          <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
</activity>
<activity android:name=".SegundaActivity"> </activity>
<activity android:name=".TerceraActivity"> </activity>

Por otro lado, sólo una de ellas puede estar definida como Main. El resto no. A no ser que queramos hacer experimentos. Si añadimos varias activities como Main, veremos que en el escritorio de nuestro Android aparecen las activities como diferentes puntos de entrada de la aplicación.

Más tarde, hablaremos de los permisos y para que sirven.

Fijaos en varios detalles:

<activity android:name=".TerceraActivity"> </activity>

El nombre de la activity, siempre va precedido por un punto. Esto tiene un significado muy importante (en caso contrario, las Activities no serán encontradas durante la ejecución).

.TerceraActivity nos está diciendo que el fichero TerceraActivity.java se encuentra justo en “src”

Si tuviesemos algo como src.activities y dentro una CuartaActivity, deberíamos indicarlo como:

<activity android:name=".activities.CuartaActivity"> </activity>

Es muy importante que seáis cuidadosos con esto para mantener un orden y una lógica en la aplicación (y obviamente, para que no haya errores por todas partes)

Primeros Conceptos

Publicado: noviembre 11, 2011 en Uncategorized

Antes de nada, recordar que voy a trabajar siempre con Eclipse, así que las capturas, serán de este IDE.

Lo primero que vamos a hacer, es crear un proyecto nuevo de Android, con File -> New -> Other -> Android Project, obteniendo el siguiente menú

Como podéis ver, tenemos varios campos que va a ser necesario rellenar antes de seguir con la creación de nuestra primera aplicación para Android.

Project Name: Es el nombre del proyecto. En mi caso, pondré AndroidToast-E1
Build Target: Es la API que usará nuestra aplicación. Aquí aparecen listados todas aquellas API que os hayáis descargado. Seleccionaré la 2.2 por ser actualmente, la más extendida.

Seguidamente, vamos a llenar las propiedades del proyecto. Importante tener muy presentes estos datos.

Application name: Es el nombre de la aplicación (ojo no tiene porqué ser el mismo que el proyecto). Es el que nos aparecerá en el móvil cuando usemos la aplicación creada.
Package Name: Es el nombre del package en estilo Java. Recomiendo algo del tipo: com.dominio.nombreapp

Lo demás lo dejamos como está y pulsamos Finish (Si le damos a Next, nos envía a la pantalla de configuración de Test. Ahora no los necesitamos). Cuando esté finalizado, tendremos en el Package Explorer una información como la siguiente:


Vamos a explicar qué es cada cosa:

- src: Es el código fuente en Java de nuestra aplicación.

- gen: Es el código que el compilador de Android genera, para que éste sea interpretado por la VM de Android (Dalvik)

- Android 2.x: Es la librería android.jar con la versión del SDK que hemos vinculado

- assets: Es la carpeta donde colocaremos todos aquellos ficheros que sean externos al programa. Los ficheros aquí contenidos, NO se compilan. Deberán accederse mediante programación en tiempo de ejecución.

- res. Es la carpeta donde están los recursos de la aplicación (iconos, layouts, textos…). A diferencia de “assets”, res sí será compilado. Eso implica que estos recursos serán de sólo lectura y no podrán ser modificados a posteriori.

– drawable-hdpi: iconos/imágenes para pantallas de alta definición
- drawable-mdpi: iconos/imágenes para pantallas de media definición
- drawable-ldpi: iconos/imágenes para pantallas de baja definición
- layout: aquí vendrán las interfaces que usaremos en la aplicación
- values: aquí vendrán definidos todos los valores que usaremos.

- AndroidManifest.xml: Es el santo grial de las aplicaciones de Android. Contiene la configuración esencial y la definición de cada actividad.