En este artículo estudiaremos los componentes de una aplicación Android y sus respectivas funciones.
Lo primero que haremos será comprender que es el contexto de una aplicación y como permite relacionar los componentes.
Luego veremos el concepto de Actividades, Intents, Servicios, BroadCast Receivers y Content Providers.
Contexto De Una Aplicación Android
El contexto de una aplicación es una interfaz entre la aplicación y el sistema operativo, la cual describe la información que representa tu aplicación dentro del ambiente del sistema operativo.
También permite acceder a los recursos de la aplicación y coordinar el funcionamiento de los bloques de la aplicación.
Cada contexto se diferencia con un ID representado con el nombre del paquete Java. Por ejemplo, Hermosa programación usa el nombre del siguiente paquete para crear aplicaciones «com.herprogramacion.app«.
El contexto representa toda la metainformación sobre las relaciones que tiene la aplicación con otras aplicaciones o el sistema y podemos implementarlo a través de la clase Abstracta Context.
¿Qué Es Una Actividad?
Una actividad es la representación visual e interactiva en tu aplicación. Por simpleza podríamos sugerir que es una pantalla de la aplicación. En las actividades presentaremos toda la interfaz necesaria para que el usuario comprenda que queremos transmitirle y como podría satisfacer sus necesidades.
Como ya has visto las actividades son representadas por la clase Java Activity. En ella encontraremos todos los métodos que representan su ciclo de vida para interactuar con Android. Veamos algunos ejemplos de actividades:
Más adelante veremos sobre los controles de interfaz usados en una Actividad (TextViews, ImageViews, Listas, CheckBoxes, etc).
Ciclo De Vida De Una Actividad En Una Aplicación Android
A diferencia de otras aplicaciones, una actividad en Android no tiene asignado un método main() como punto de entrada principal, ya que su inicio es responsabilidad de la capa de Framework para aplicaciones. En esta capa se encuentra el servicio Activiy Manager, quién se encarga de crear, destruir y manejar todas las actividades de tu aplicación.
Una actividad puede interpretarse como una máquina de estados que está pendiente de las acciones del usuario. Aunque el programador no puede controlar la forma en que se iniciará, si podemos decidir que sentencias se ejecutarán en cada estado.
Los estados por los cuales puede transcurrir una aplicación son los siguientes: Creación, Ejecución, Reanudación, Pausa, Parada y Destrucción. A la relación entre ellos se le llama Ciclo de vida de una actividad.
Cada transición entre estados representa un método de retrollamada (callback) sobre la actividad. Algunos de estos métodos son sobrescritos automáticamente en los proyectos de Android Studio, principalmente el método onCreate(). Este método se dispara cuando hay una transición desde que el usuario hace clic en el icono de la actividad hasta su ejecución.
onCreate() luce más o menos así:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my); }
Así mismo encontramos otros métodos callback como: onStart(), onRestart(), onResume(), onPause(), onStop() y onDestroy(). La siguiente ilustración representa las respectivas transiciones entre estados a través de estos métodos:
- Creación: Una actividad se ha creado cuando su estructura se encuentra en memoria, pero esta no es visible aun. Cuando el usuario presiona sobre el icono de la aplicación en su dispositivo, el método onCreate() es ejecutado inmediatamente para cargar el layout de la actividad principal en memoria.
- Ejecución-Reanudación: Después de haber sido cargada la actividad se ejecutan en secuencia a el método onStart() y onResume(). Aunque onStart() hace visible la actividad, es onResume() quien le transfiere el foco para que interactúe con el usuario.
- Pausa: Una actividad está en pausa cuando se encuentra en la pantalla parcialmente visible. Un ejemplo sería cuando se abren diálogos que toman el foco superponiéndose a la actividad. El método llamado para la transición hacia la pausa es onPause().
- Detención: Una actividad está detenida cuando no es visible en la pantalla, pero aun se encuentra en memoria y en cualquier momento puede ser reanudada. Cuando una aplicación es enviada a segundo plano se ejecuta el método onStop(). Al reanudar la actividad, se pasa por el método onRestart() hasta llegar a el estado de ejecución y luego al de reanudación.
- Destrucción: Cuando la actividad ya no existe en memoria se encuentra en estado de destrucción. Antes de pasar a destruir la aplicación se ejecuta el método onDestroy(). Es común que la mayoría de actividades no implementen este método, a menos que deban destruir procesos (como servicios) en segundo plano.
Aunque tu aplicación puede tener varias actividades en su estructura, se debe definir una actividad principal. Para hacerlo se debe especificar en tu archivo Android Manifest un componente <actitivy>, con un componente hijo <intent-filter>. Dentro de este componente declararas dos nuevos componentes, <action> y <category>. Al primero le asignaras el elemento enumerado MAIN y al segundo el elemento enumerado LAUNCHER.
<activity android:name=".MyActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Intents para Comunicar Componentes Android
Un Intent es un mensaje que se envía de un componente a otro, o entre una aplicación a otra para comunicarse. Podrían asemejarse a los links entre páginas web. Los Intents también pueden guardar información primitiva de utilidad entre la comunicación.
Por ejemplo, supongamos que tu aplicación produce algún resultado sobre las estadísticas financieras de una empresa y deseas enviarlas como correo adjunto en Gmail.
¿Crees que es necesario crear una actividad dentro de nuestra aplicación para que gestione correos electrónicos en Gmail?
!No¡…A través de un Intent puedes enviar la información hacia la aplicación de Gmail para que ella se encargue del resto.
Veamos un simple gráfico ilustrativo:
Así mismo podemos crear comunicaciones entre las actividades de nuestra aplicación para compartir algunos datos.
Los Intents pueden ser implícitos o explícitos. Son explícitos cuando ejecutamos un componente en específico. Son implícitos cuando se entrega una referencia genérica sobre alguna condición, y aquellas entidades que cumplan ese requisito serán presentadas como candidatas para la tarea.
Un ejemplo de Intent implícito sería cuando deseas compartir un sitio web en alguna red social. Para ello Android nos ofrece en un pequeño dialogo de lista para que elijamos entre cuales de todas las aplicaciones sociales deseamos elegir para compartir. No especificamos que aplicación queríamos, simplemente se mostraron todas las aplicaciones que podrían responder a ese tipo de acción.
Un Intent explicito se da cuando invocamos una actividad con un tipo de clase especifico. Por ejemplo, supón que dentro de nuestra aplicación tenemos dos actividades llamadas A y B. Si decidimos iniciar la actividad B desde la actividad A usaríamos un Intent explicito debido a que «B» es un tipo definido.
Servicios para Trabajos en Segundo Plano
Un servicio es una entidad que ejecuta instrucciones en segundo plano sin que el usuario lo note en la interfaz. Son muy utilizados para realizar acciones de larga duración mientras las actividades muestran otro tipo de información. Por ejemplo guardar la información en la base de datos, escuchar música mientras se ejecuta la aplicación, administrar conexiones de red, etc. Un Servicio no es afectado por la mayoría de transiciones en el ciclo de vida de una actividad.
-¿Y qué utilidad tienen que corran en segundo plano?
– Pues fíjate que todos las actividades que tu construyas en tu aplicación tienden por defecto a ejecutarse en un mismo hilo llamado UI thread. Esta situación hace que una instrucción no se ejecute hasta que se termine el proceso actual.
-Ammm!
– Por ejemplo, esperar que se carguen los resultados de una consulta en la base de datos antes de mostrar una actividad, no es lo más cómodo para el usuario. Es por eso que necesitamos los servicios para permitir ejecutar instrucciones de larga duración en otro hilo simultáneo y así no alterar las respuestas de la interfaz.
Los servicios también tienen un ciclo de vida como las actividades, pero este es más corto. Solo se comprende de los estados de Creación, Ejecución y Destrucción.
Intercambiar Datos con Content Providers
Un Content Provider es una interfaz que permite intercambiar información persistente y estructurada entre dos aplicaciones. Cada aplicación tiene protegida su información, de modo que están aisladas de los contextos de otras aplicaciones.
Aunque los Intents permiten intercambiar pequeños datos entre aplicaciones, un Content Provider permite extender a mejores usos para intercambiar información persistente en la base de datos entre aplicaciones.
Un ejemplo sería una aplicación que necesite usar la base de datos de la aplicación de contactos de Android. Para ello se usa un Content Provider que nos ayude. Veamos una ilustración sencilla de la relación:
Por defecto, el API de Android trae consigo Content Providers predefinidos para intercambiar información de audio, vídeo, imágenes, e información personal. Pero si en algún momento deseas intercambiar información con una estructura personalizada debes crear tu propia subclase heredada de la clase ContentProvider.
Los Content Providers son excelentes para trabajar en segundo plano para cargar información. Esta ventaja permite proporcionar excelente experiencia al usuario al usar la aplicación, debido a que no habrá interferencia entre las consultas a la base de datos y las respuestas de la interfaz.
Capturar Mensajes con los Broadcast Receivers
Los Broadcast Receivers son Triggers implementados para activarse cuando un Intent se envía entre componentes. Dichos eventos se relacionan con el cambio de características en un componente o el cambio de estado.
Los Broadcasts son muy útiles para monitorear los estados de nuestra aplicación, lo que permite ejecutar instrucciones si en algún momento sucede alguna acción prevista.
Aunque un Broadcast Receiver no se carga en memoria inicialmente, el está a la espera de algún evento para ejecutarse. Por ejemplo, es común hacer seguimiento al uso de la batería con broadcasts para optimizar su rendimiento. O también cuando hay correos nuevos en la bandeja de entrada.
Conclusión
¿Conseguiste una visión general de lo que debes aprender?
Como viste, una aplicación Android puede contener varios componentes dependiendo de su propósito ante el usuario.
Es buena práctica diseñar la arquitectura de tu aplicación antes de desarrollar, basándote en los componentes necesarios para el funcionamiento.
El siguiente paso es aprender a crear actividades y comunicarlas entre sí.