viernes, 1 de abril de 2011

Programación Android: Componentes de Construcción

Sobre la arquitectura antes presentada en este blog, tenemos que saber que existen 4 tipos de bloques de construcción de cualquier aplicación Android. No necesariamente los utilizaremos a estos 4 tipos en nuestra aplicación, pero sin duda que tendremos más de uno y algunas combinaciones entre tipos. Entonces, recordando que en el primer capítulo ya presentamos los componentes Activity’s e Intent’s, brevemente presentemos los principales Componentes de Construcción con los que vamos a trabajar, teniendo presente que Activities e Intents son los dos componentes más importantes de la arquitectura de las aplicaciones Android.

Algo a remarcar es que todos los componentes son configurados en el archivo AndroidManifest.xml, y que cada componente puede ser iniciado independientemente, pudiendo también ser reutilizado por otras aplicaciones.

Activity: Es el componente mas genérico y más común de la plataforma. Para crear una Activity, tenemos que escribir una clase Java que herede de la superclase Activity, ya definida en las librerías. En el capitulo anterior dijimos que una Activity es un elemento sobre el que se construye la aplicación y que tiene un ciclo de vida bastante complejo, el cual en breve presentaremos. Ahora bien, podemos decir que estas Activities son las pantallas de la aplicación, en las que podemos cargar elementos de la interfaz de usuario y capturar eventos. También son los puntos entrantes de la aplicación y puede haber más de una Activity por proyecto. Las actividades pueden declarar el tipo de acciones a ejecutar y los tipos de datos que pueden manejar. Entonces, podemos resumirlo diciendo que la principal función es la de mostrar pantallas y que pueden reaccionar a los eventos del usuario. Para pasar de un elemento Activity a otro se utiliza generalmente mediante el método startActivity() o el método startActivityForResult() cuando se necesita una llamada síncrona. La navegación entre pantallas se lleva a cabo mediante una clase especial llamada Intent que presentaremos a continuación. Si miramos el archivo AndroidManifest.xml quedaría algo así:

android:label="@string/app_name">

Y ahora veamos que ese tag .

Intent: Este término ya lo presentamos también en el primer capítulo, dijimos que la breve definición de la documentación dice que “Un Intent es la descripción abstracta de una operación que se va a llevar a cabo”. Mejor dicho, un Intent es una clase Java que nos permite especificar una Activity a ejecutar, y llamar a uno de los métodos de la clase Activity con ese Intent de parámetro. Entonces, si antes dijimos que las Activities son la interfaz grafica, ahora podemos decir que las “intenciones” o Intents, son la forma de invocar estas Activities.

Desde nuestros programas tenemos dos formas de invocar a una Activity mediante Intent's: Explícitamente o Implícitamente.

-Explícitamente: creamos un Intent y en su constructor indicamos el nombre de la clase correspondiente a la actividad, le pasamos un Context para que sepa en qué paquete buscar, y luego llamamos a startActivity(). Para pasarle datos, como ya vimos en el ejemplo mejorado del primer capítulo, tomamos del Intent el objeto Bundle del método onCreate de la instancia. Recordemos el ejemplo ya presentado:

// FrmMensaje es la clase de la actividad que queremos iniciar.

// HolaMundoPlus.this indica el Context actual, para saber en qué package buscar

Intent intent = new Intent(HolaMundoPlus.this, FrmMensaje.class);

Bundle bundle = new Bundle();

bundle.putString("NOMBRE ", txtNombre.getText().toString());

// la información se recuperará en el objeto Bundle de onCreate

intent.putExtras(bundle);

startActivity(intent);

-Implícitamente: es también a través de la clase Intent. En este caso no se indica el nombre de la clase correspondiente a la actividad a invocar, sino que se establecen una serie de criterios, para que el sistema elija una actividad que cumpla esos criterios.

Sobre esos criterios a cumplir, tenemos que decir que, a un Intent, al momento de declararlo en el archivo AndroidManifest.xml podemos asociarle una acción, unos datos y una categoría. Estas acciones son cadenas de texto estándar que describen lo que la actividad puede hacer, por ejemplo, android.intent.action.VIEW es una acción que indica que la actividad puede mostrar datos al usuario. En el ejemplo usamos la línea:

También se puede declarar el tipo de dato que maneja, por ejemplo, “com.libro.android.curso.entidades/estudiante”. Por último, podemos definir una categoría, que básicamente indica si la actividad va a ser lanzada desde el lanzador de aplicaciones, desde el menú de otra aplicación o directamente desde otra actividad. En el AndroidManifest.xml todo junto quedaría así:

com.libro.android.curso.entidades/estudiante " />

Entonces, para utilizar la invocación implícita de una actividad a través de un Intent, en vez de asignar el nombre de la clase, le asignamos una de las acciones que puede realizar, con el tipo de datos apropiado.

Service: es código que se ejecuta en segundo plano, comúnmente los programadores decimos que se ejecuta en background. Este codigo no necesita de una interface de usuario en su ciclo de vida. ¿Cuándo lo utilizamos? Cuando sabemos que el ciclo de vida de una aplicación es prolongado, debe de incluirse en un Service. Los servicios se inician con el método startService(Intent) de la clase abstracta Context. Al utilizar este tipo de componente, es importante tener presente su ciclo de vida, que presentaremos un poco más adelante, ya que tendremos que tener en cuenta las prioridades que gestiona el sistema, en relación al tiempo de vida de los componentes y la influencia del servicio creado por nosotros en esta jerarquía de prioridades.

Entonces, a modo de resumen, los Service’s corren en el fondo sin interfaz, para usarlo uno debe hacer bind del service, y se usa la interfaz expuesta por el service. También, como en los demás componentes, el servicio tiene que estar en el archivo Manifest :

Si tenemos que presentar un ejemplo, sin duda "un reproductor de música" es lo más grafico que se me ocurre, o también un contador que se ejecute, al igual que el reproductor, en background. Ya más adelante, realizaremos unos ejemplos.

Broadcast Receiver Si una aplicación desea recibir y responder a un evento global como por ejemplo una llamada de teléfono o un mensaje de texto que llega, esta aplicación debe registrarse como BroadcastReceiver. Es un componente que recibe notificaciones y reacciona a ellas, corriendo en el fondo sin interfaz. Por ejemplo, en un juego se podría usar para grabar el estado y llevar el juego a pausa en caso de que se quede sin batería o el jugador reciba una llamada.

Content Provider Si una aplicación administra datos y debe mostrarlos a otras aplicaciones, es necesario implementar ContentProvider. Es un estándar de métodos para que la aplicación pueda acceder a los datos, ya sea en operaciones de lectura o escritura. ContentProvider puede brindar datos a una actividad o a un servicio incluidos en la misma aplicación o en otra diferente. Se puede considerar como una capa abstracta de datos para sus clientes y que centraliza los métodos de persistencia de datos.

A modo de resumen, podemos decir que el componente ContentProvider es una forma estándar de proveer a una aplicación de contenido, se ejecuta en background sin interfaz, y guarda datos en el sistema de archivos o en una base de datos SQLite, por ejemplo. Algo importante es que, el programador también puede declarar e implementar sus propios ContentProvider. Por ejemplo, Android contiene un par de ContentProviders definidos, como el que nos permite acceder a los contactos del teléfono.

Ya con la arquitectura de las aplicaciones en mente y estos bloques de construcción, tenemos que destacar que las aplicaciones son ejecutadas dentro de un proceso Linux, y esto implica que es el sistema operativo quien determina el tiempo y el ciclo de vida de la aplicación, es decir, no es controlado esto por la misma aplicación, sino que es el resultado de factores como las aplicaciones que están funcionando, qué prioridad tienen para el usuario y cuánta memoria queda disponible en el sistema.

Al ocuparse Android de gestionar estos procesos de cada aplicación, también nos brinda algunos beneficios en relación a la seguridad, gestión de memoria o tiempo de CPU del dispositivo. El usuario final no tiene que preocuparse si existen o no recursos para ejecutar la aplicación, ni si existen o no recursos para abrir tal o cual aplicación, simplemente sabe que por medio de un clic pasa de una aplicación a otro y puede volver a cualquiera de estas en el momento que quiera.

Por otro lado, el tiempo de vida del proceso asociado a una aplicación está condicionado también por los componentes declarados en el archivo AndroidManifest.xml, ya que el sistema tiene la facultad de detener el proceso, si así lo considera apropiado, sin importarle lo que esté realizando ese proceso.

En esta entrada de blog un poco teórica, se ha estudiado cómo diferentes aplicaciones de Android se pueden diseñar con tres bloques de construcción básicos: el contexto, actividades, e intenciones. Cada aplicación esta formada por una o más actividades.

La funcionalidad de alto nivel de aplicación es accesible a través del contexto de aplicación. Cada actividad tiene una función especial y (por lo general) su propio diseño, o una interfaz de usuario.

No hay comentarios:

Publicar un comentario