Ciclo de vida de una actividad



Como vimos en el post “Procesos en Android” el sistema operativo es el encargado de pausar, parar o destruir nuestra aplicación según las necesidades de recursos del dispositivo, aún así,  nosotros como desarrolladores debemos aprender a controlar todos estos eventos para hacer nuestras aplicaciones robustas y mejorar el rendimiento de los teléfonos.
Para entender esta parte explicaré el ciclo de vida de una actividad, que representa cada una de las pantallas de nuestra aplicación. A continuación cito un diagrama que también puedes encontrar en la documentación oficial de Android Developers:
Pasemos a explicar cada uno de los métodos:
  • onCreate(): Se dispara cuando la Activity es llamada por primera vez. Aquí es donde debemos crear la inicialización normal de la aplicación, crear vistas, hacer los bind de los datos, etc. Este método te da acceso al estado de la aplicación cuando se cerró. Después de esta llamada siempre se llama al onStart().
  • onRestart(): Se ejecuta cuando tu Activity ha sido parada, y quieres volver a utilizarla. Si ves el diagrama podrás ver que después de un onStop() se ejecuta el onRestart() e inmediatamente llama a un onStart().
  • onStart(): Se ejecuta cuando la Activity se está mostrando apenas en la pantalla del dispositivo del usuario.
  • onResume(): Se ejecuta una vez que la Activity ha terminado de cargarse en el dispositivo y el usuario empieza a interactuar con la aplicación. Cuando el usuario ha terminado de utilizarla es cuando se llama al método onPause().
  • onPause(): Se ejecuta cuando el sistema arranca una nueva Activity que necesitará los recursos del sistema centrados en ella. Hay que procurar que la llamada a este método sea rápida ya que hasta que no se termine su ejecución no se podrá arrancar la nuevaActivity. Después de esta llamada puede venir un onResume() si la Activity que haya ejecutado el onPause() vuelve a aparecer en primer plano o un onStop() si se hace invisible para el usuario.
  • onStop(): Se ejecuta cuando la Activity ya no es visible para el usuario porque otra Activityha pasado a primer plano. Si vemos el diagrama, después de que se ha ejecutado este método nos quedan tres opciones: ejecutar el onRestart() para que la Activity vuelva a aparecer en primer plano, que el sistema elimine este proceso porque otros procesos requieran memoria o ejecutar el onDestroy() para apagar la aplicación.
  • onDestroy(): Esta es la llamada final de la Activity, después de ésta, es totalmente destruida. Esto pasa por los requerimientos de memoria que tenga el sistema o porque de manera explícita el usuario manda a llamar este método. Si quisiéramos volver a ejecutar la Activity se arrancaría un nuevo ciclo de vida.

Procesos en Android


En la mayoría de los casos, una aplicación Android se ejecuta en su propio proceso de Linux. Este proceso es creado para la aplicación cuando la arrancamos y seguirá corriendo hasta que no sea necesario y el sistema reclame recursos para otras aplicaciones y se los de a éstas.
Así es, el tiempo de vida de un proceso en Android es manejada por el sistema operativo, basándose en las necesidades del usuario, los recursos disponibles, etc. Si tenemos una aplicación que está consumiendo muchos recursos y arrancamos otra nueva aplicación, el sistema operativo probablemente le diga a la aplicación que se queda en segundo plano que libere todo lo que pueda, y si es necesario la cerrará.
En Android los recursos son normalmente muy limitados y por eso el sistema operativo tiene más control sobre las aplicaciones que en programas de escritorio.
Para determinar qué procesos eliminar ante un escenario dónde el dispositivo tenga poca batería u otros en los que sea de relevante importancia administrar los recursos, Android les asigna una prioridad a cada uno de ellos basándose en la siguiente jerarquía:
  1. Foreground Process: Es la aplicación que contiene la actividad ejecutada en primer plano en la pantalla del usuario y con la cuál está interactuando ahora mismo  (Se ha llamado a su método onResume()). Por lo regular habrá muy pocos procesos de este tipo corriendo a la vez en el sistema y son aquellos que se eliminarán como última opción si la memoria es tan baja que ni matando al resto de procesos tenemos los recursos necesarios.
  2. Visible Process: Es un proceso que aloja una Activity que no se está ejecutando en primer plano (es decir, su método onPause() ha sido llamado). Un ejemplo puede ser la aplicación de correo en la cuál demos click en algún enlace de interés que nos lance el navegador, este pasaría a ser el Foreground Process dejando a la aplicación de correo en el concepto de Visible Process. Este tipo de procesos se cerrarán únicamente cuando el sistema no tenga los recursos necesarios para mantener corriendo todos los procesos que estén en primer plano.
  3. Service Process: Son aquellos que corren cuando un Service ha sido invocado. Estos procesos hacen cosas en segundo plano que normalmente son importantes para el usuario (conexión con servidores, actualización del GPS, reproductor de música, etc.), el sistema nunca va a liquidar un servicio a menos que sea necesario para mantener vivos todos los Visible y Foreground.
  4. Background Process: Es un proceso que contiene una Activity que actualmente no es visible por el usuario y que ya no tienen demasiada importancia. Por ejemplo, los programas que arrancó el usuario hace tiempo y no los ha vuelto a usar, pasan a estar en background. Por eso es importante que cuando nuestra aplicación pase a Background, el sistema libere, en la medida de lo posible, todos los recursos que pueda para que su rendimiento sea óptimo.
  5. Empty Process: Es un proceso que no aloja ningún tipo de componente. Su razón de ser es el de tener una caché disponible para la próxima aplicación que lance el usuario. Es común que el sistema elimine este tipo de procesos con frecuencia para así poder obtener memoria disponible.
Una vez entendido esto podemos pasar a conocer a las actividades y su ciclo de vida. Espero que este post te haya sido de utilidad, ¡saludos!.

Componentes de una aplicación Android


Las aplicaciones Android se construyen mediante bloques esenciales de componentes, cada uno de los cuales existe como una entidad propia y desempeña un papel específico; cada elemento es una pieza única que ayuda a definir el comportamiento general de la aplicación. Es importante mencionar que algunos de estos elementos son el punto de entrada para que los usuarios interactúen con la aplicación y en muchos casos veremos que unos elementos dependen de otros.
Hay cuatro tipos de componentes en una aplicación Android. Cada uno de ellos tiene un propósito y un ciclo de vida distinto que define cómo se crea y se destruye el componente.
Activities (actividades). Es el bloque encargado de construir la interfaz de usuario. Puedes pensar en una actividad como el análogo de una ventana en una aplicación de escritorio. En las actividades recae la responsabilidad de presentar los elementos visuales y reaccionar a las acciones del usuario.
Si bien podemos pensar en actividades que no posean una interfaz de usuario, regularmente el código en estos casos se empaqueta en forma de content providers (proveedores de contenido) y services (servicios) que detallaremos en un momento.
Toda actividad se inicia como respuesta a un Intent.
Intents (intenciones). Son los mensajes del sistema que se encuentran corriendo en el interior del dispositivo. Se encargan de notificar a las aplicaciones de varios eventos: cambios de estado en el hardware (ej. cuando se inserta unaSD al teléfono), notificaciones de datos entrantes (ej. cuando llega un SMS) y eventos en las aplicaciones (ej. cuando una actividad es lanzada desde el menú principal).
Así como podemos crear actividades que respondan a las intenciones, podemos crear también intenciones que lancen actividades o usarlas para detonar eventos ante algunas situaciones específicas (ej. que el teléfono nos notifique por medio de un mensaje cuando nuestra localización esté a 10 mts del punto de destino). Es importante mencionar que el sistema es el que elige entre las actividades disponibles en el teléfono y dará respuesta a la intención con la actividad más adecuada.
Content providers (proveedores de contenido). Este elemento ofrece un conjunto de datos almacenados en el dispositivo para que se puedan accesar y compartir por varias aplicaciones. Nosotros podemos guardar datos en archivos del sistema, en una base de datos en SQLite, en la web o en cualquier otro lugar de almacenamiento persistente a la que la aplicación pueda tener acceso. A través del proveedor de contenido, otras aplicaciones pueden consultar o incluso modificar los datos (solamente si el proveedor de contenidos de esa aplicación lo permite).
El modelo de desarrollo en Android nos invita a los desarrolladores a pensar siempre en hacer los datos de nuestras aplicaciones disponibles para otras aplicaciones. De manera que cuando creamos un proveedor de contenido, podemos tener un control completo de nuestros datos y definir la forma en que éstos serán accesados.
Un ejemplo sencillo de esto es el proveedor de contenido que tiene Android para gestionar la información de contactos (agenda) del teléfono. Cualquier aplicación con los permisos adecuados puede realizar una consulta a través de un proveedor de contenido comoContactsContract.Data para leer y escribir información sobre una persona en particular.
Services (servicios). Las actividades, las intenciones y los proveedores de contenido explicados arriba son de corta duración y pueden ser detenidos en cualquier momento. Por el contrario, los servicios están diseñados para seguir corriendo, y si es necesario, de manera independiente de cualquier actividad. El ejemplo más simple para aterrizar este concepto es el del reproductor de música, que es un servicio que puede mantenerse corriendo mientras mandamos un SMS o realizamos alguna otra función en nuestro teléfono.
Dependiendo de la fuente consultada o el autor, podrán encontrar también un elemento llamado Broadcast receivers (receptores de radiodifusión). Este componente responde a las notificaciones de difusión de todo el sistema como por ejemplo que la pantalla se ha apagado, que la batería del teléfono está por terminarse o que una fotografía ha sido tomada. Las aplicaciones también pueden lanzar este tipo de notificaciones, un ejemplo de ello es el aviso de que alguna información ha terminado de descargarse en el dispositivo y se encuentran disponibles para su utilización.
Aunque los broadcaster receivers no muestran una interfaz de usuario, pueden crear notificaciones en la barra de estado del teléfono para avisarle al usuario cuando un evento de este tipo se genera. Podemos pensar en estos elementos como el medio por el cual otros componentes pueden ser iniciados en respuesta a algún evento. Cabe mencionar que cada una de las emisiones de los broadcaster receivers se representa como una intención.
Un aspecto único y útil del diseño del sistema operativo Android es que cualquier aplicación puede hacer uso de otro componente de otra aplicación.  Supongamos que la aplicación requiere que el usuario tome una fotografía con la cámara del teléfono; es probable que exista otra aplicación que haga exactamente eso, por lo que resultará más fácil reutilizar esa función que programar una específica en nuestra aplicación. Para ello no es necesario incluir o vincular el código de la aplicación de la cámara, simplemente hará falta iniciar la actividad que se encargue de capturar la foto. Una vez hecho, la foto estará disponible para usarla en la aplicación “principal”. Para el usuario parecerá que la cámara de su teléfono es una parte de la aplicación.
Debido a que el sistema Android ejecuta cada una de las aplicaciones en un proceso separado con permisos de archivos que pueden restringir el acceso a otras aplicaciones, las aplicaciones no pueden activar de forma directa un componente de otra aplicación. El único que puede hacer esto es el sistema operativo en sí. Por lo tanto, para activar un elemento de otra aplicación, debemos pasarle un mensaje al sistema dónde se especifique qué elemento es el que necesitamos correr. De esta manera el sistema activará el componente y podremos manipularlo según sea nuestra necesidad.
Todos los elementos expuestos en este post son objetos y su comportamiento está definido en su correspondiente clase base convirtiendo a cada elemento en una subclase del elemento original. Esto lo hacemos por medio de la herencia, una característica básica de Java y de los lenguajes orientados a objetos, y que nos evitará tener que volver a implementar aspectos comunes en todos los objetos del mismo tipo, y poder al mismo tiempo, personalizar su comportamiento tanto como lo necesite nuestra aplicación por medio de la sobre escritura de los métodos de la clase padre.

Arquitectura de Android


Para empezar con el desarrollo de aplicaciones en Android es importante conocer cómo está estructurado este sistema operativo. A esto le llamamos arquitectura y en el caso de Android está formada por varias capas que facilitan al desarrollador la creación de aplicaciones. Además, esta distribución permite acceder a las capas más bajas mediante el uso de librerías para que así el desarrollador no tenga que programar a bajo nivel las funcionalidades necesarias para que una aplicación haga uso de los componentes de hardware de los teléfonos.
Cada una de las capas utiliza elementos de la capa inferior para realizar sus funciones, es por ello que a este tipo de arquitectura se le conoce también como pila. Para entender mejor, a continuación cito el diagrama de la arquitectura de Android tomada del sitio oficial de Android developers:

Explicamos ahora cada una de las capas iniciando de abajo hacia arriba.
Kernel de Linux. Como dijimos en el artículo ¿Qué es Android?, el núcleo del sistema operativo Android está basado en el kernel de Linux versión 2.6, similar al que puede incluir cualquier distribución de Linux, como Ubuntu, solo que adaptado a las características del hardware en el que se ejecutará Android, es decir, para dispositivos móviles.
El núcleo actúa como una capa de abstracción entre el hardware y el resto de las capas de la arquitectura. El desarrollador no accede directamente a esta capa, sino que debe utilizar las librerías disponibles en capas superiores. De esta forma también nos evitamos el hecho de quebrarnos la cabeza para conocer las características precisas de cada teléfono. Si necesitamos hacer uso de la cámara, el sistema operativo se encarga de utilizar la que incluya el teléfono, sea cual sea. Para cada elemento de hardware del teléfono existe un controlador (o driver) dentro del kernel que permite utilizarlo desde el software.
El kernel también se encarga de gestionar los diferentes recursos del teléfono (energía, memoria, etc.) y del sistema operativo en sí: procesos, elementos de comunicación (networking), etc.
Librerías. La siguiente capa que se sitúa justo sobre el kernel la componen las bibliotecas nativas de Android, también llamadas librerías. Están escritas en C o C++ y compiladas para la arquitectura hardware específica del teléfono. Estas normalmente están hechas por el fabricante, quien también se encarga de instalarlas en el dispositivo antes de ponerlo a la venta. El objetivo de las librerías es proporcionar funcionalidad a las aplicaciones para tareas que se repiten con frecuencia, evitando tener que codificarlas cada vez y garantizando que se llevan a cabo de la forma “más eficiente”.
Entre las librerías incluidas habitualmente encontramos OpenGL (motor gráfico), Bibliotecas multimedia (formatos de audio, imagen y video), Webkit (navegador), SSL (cifrado de comunicaciones), FreeType (fuentes de texto), SQLite (base de datos), entre otras.
Entorno de ejecución. Como podemos apreciar en el diagrama, el entorno de ejecución de Android no se considera una capa en sí mismo, dado que también está formado por librerías. Aquí encontramos las librerías con la funcionalidades habituales de Java así como otras específicas de Android.
El componente principal del entorno de ejecución de Android es la máquina virtual Dalvik. Las aplicaciones se codifican en Java y son compiladas en un formato específico para que esta máquina virtual las ejecute. La ventaja de esto es que las aplicaciones se compilan una única vez y de esta forma estarán listas para distribuirse con la total garantía de que podrán ejecutarse en cualquier dispositivo Android que disponga de la versión mínima del sistema operativo que requiera la aplicación.
Cabe aclarar que Dalvik es una variación de la máquina virtual de Java, por lo que no es compatible con el bytecode Java. Java se usa únicamente como lenguaje de programación, y los ejecutables que se generan con el SDK de Android tienen la extensión .dex que es específico para Dalvik, y por ello no podemos correr aplicaciones Java en Android ni viceversa.
Framework de aplicaciones. La siguiente capa está formada por todas las clases y servicios que utilizan directamente las aplicaciones para realizar sus funciones. La mayoría de los componentes de esta capa son librerías Java que acceden a los recursos de las capas anteriores a través de la máquina virtual Dalvik. Siguiendo el diagrama encontramos:
  1. Activity Manager. Se encarga de administrar la pila de actividades de nuestra aplicación así como su ciclo de vida.
  2. Windows Manager. Se encarga de organizar lo que se mostrará en pantalla. Básicamente crea las superficies en la pantalla que posteriormente pasarán a ser ocupadas por las actividades.
  3. Content Provider. Esta librería es muy interesante porque crea una capa que encapsula los datos que se compartirán entre aplicaciones para tener control sobre cómo se accede a la información.
  4. Views. En Android, las vistas los elementos que nos ayudarán a construir las interfaces de usuario: botones, cuadros de texto, listas y hasta elementos más avanzados como un navegador web o un visor de Google Maps.
  5. Notification Manager. Engloba los servicios para notificar al usuario cuando algo requiera su atención mostrando alertas en la barra de estado. Un dato importante es que esta biblioteca también permite jugar con sonidos, activar el vibrador o utilizar los LEDs del teléfono en caso de tenerlos.
  6. Package Manager. Esta biblioteca permite obtener información sobre los paquetes instalados en el dispositivo Android, además de gestionar la instalación de nuevos paquetes. Con paquete nos referimos a la forma en que se distribuyen las aplicaciones Android, estos contienen el archivo .apk, que a su vez incluyen los archivos .dex con todos los recursos y archivos adicionales que necesite la aplicación, para facilitar su descarga e instalación.
  7. Telephony Manager. Con esta librería podremos realizar llamadas o enviar y recibir SMS/MMS, aunque no permite reemplazar o eliminar la actividad que se muestra cuando una llamada está en curso.
  8. Resource Manager. Con esta librería podremos gestionar todos los elementos que forman parte de la aplicación y que están fuera del código, es decir, cadenas de texto traducidas a diferentes idiomas, imágenes, sonidos o layouts. En un post relacionado a la estructura de un proyecto Android veremos esto más a fondo.
  9. Location Manager. Permite determinar la posición geográfica del dispositivo Android mediante GPS o redes disponibles y trabajar con mapas.
  10. Sensor Manager. Nos permite manipular los elementos de hardware del teléfono como el acelerómetro, giroscopio, sensor de luminosidad, sensor de campo magnético, brújula, sensor de presión, sensor de proximidad, sensor de temperatura, etc.
  11. Cámara: Con esta librería podemos hacer uso de la(s)  cámara(s) del dispositivo para tomar fotografías o para grabar vídeo.
  12. Multimedia.Permiten reproducir y visualizar audio, vídeo e imágenes en el dispositivo.
Aplicaciones. En la última capa se incluyen todas las aplicaciones del dispositivo, tanto las que tienen interfaz de usuario como las que no, las nativas (programadas en C o C++) y las administradas (programadas en Java), las que vienen preinstaladas en el dispositivo y aquellas que el usuario ha instalado.
En esta capa encontramos también la aplicación principal del sistema: Inicio (Home) o lanzador (launcher), porque es la que permite ejecutar otras aplicaciones mediante una lista y mostrando diferentes escritorios donde se pueden colocar accesos directos a aplicaciones o incluso widgets, que son también aplicaciones de esta capa.
Como podemos ver, Android nos proporciona un entorno sumamente poderoso para que podamos programar aplicaciones que hagan cualquier cosa. Nada dentro de Android es inaccesible y podemos jugar siempre con las aplicaciones de nuestro teléfono para optimizar cualquier tarea.
El potencial de Android se sitúa en el control total que se le da al usuario para que haga de su teléfono un dispositivo a su medida.

¿Qué es Android?


Sé que la mayoría de los lectores de este blog se estarán preguntando la razón de ser de este post. Android para muchos de ustedes no representa algo nuevo pero muchos de mis conocidos ajenos al área tecnológica quizás estén estrenando un nuevo teléfono cuya “pantallita” es diferente al de un Blackberry o un iPhone y al escuchar Android se imaginen únicamente un simpático monito verde que venía dibujado en la caja y no más.
Así que para esas situaciones en las que te miren con cara de WTF cuando estés emocionado contando tal o cual cosa de Android, este post será una buena referencia para que invites a tus amigos y se quiten de la duda y no está de más para alimentar la cultura general. Sin más comencemos.
¿Android?
Android es una pila de software pensada inicialmente para teléfonos móviles (smartphones)  que incluye un sistema operativomiddleware y una capa aplicaciones para que el teléfono pueda realizar funciones más allá de los dispositivos que se usaban antaño.
Dejando un poco de lado los tecnicismos, Android es otra de las opciones de interfaces y características que podemos encontrar en teléfonos móviles; así como podemos identificar aspectos particulares de un Nokia cuyo sistema operativo es Symbian, o un iPhone con iOS o incluso los Blackberry, también existen cosas muy específicas en los teléfonos que funcionan con Android.
Ahora volvámonos más técnicos. Android es un sistema operativo basado en el kernel de Linux, por esa razón tiene inmersas las características de ser libre, gratuito y multiplataforma. Cualquier desarrollador puede crear aplicaciones para Android sin la necesidad de pagar membresías anuales para obtener el kit de desarrollo (SDK).
Android utiliza una variación del lenguaje de programación Java que es diferente a la Java ME. Si has desarrollado en Java, seguramente conocerás lo que es trabajar con una máquina virtual que sirve para interpretar todo ese código que genera nuestro programa (bytecode) y pueda ejecutarse. Pues bien, Android, tiene una adaptación de esta máquina virtual y se llama Dalvik. Pese a las pesadillas que tengas de la virtual machine por default de Java, Dalvik es una excelente versión que optimiza muchas cosas en la plataforma y te sorprenderá saber que la rapidez de Android y de algunas aplicaciones se debe precisamente a esto.
Cabe mencionar que el sistema operativo proporciona todas las interfaces necesarias para desarrollar aplicaciones que accedan a las funciones del teléfono (como el GPS, las llamadas, la agenda, etc.) de una forma muy sencilla utilizando Java.
Y en los orígenes alguien creó Android…
Android era un sistema operativo para móviles prácticamente desconocido propiedad de una empresa llamada Android Inc. hasta que en 2005 Google lo compró. Actualmente Andy Rubin, el creador de Android, trabaja como vicepresidente de ingeniería de Google y tiene bajo su mando este proyecto.
En noviembre de 2007 sólo circulaban rumores de que el gigante de Internet tenía en planes lanzar un proyecto para móviles, y precisamente por esas fechas se lanzó la Open Handset Alliance, que agrupaba a muchos fabricantes de teléfonos móviles, chipsets y Google y se proporcionó la primera versión de Android, junto con el SDK para que los programadores empezaran a crear sus aplicaciones para este sistema.
Aunque los inicios fueran un poco lentos, debido a que se lanzó el sistema operativo antes que el primer móvil, rápidamente se ha colocado como una plataforma que ya se ha ganado muchos adeptos y que ha demostrado una velocidad de madurez importante debido a los diferentes fabricantes que han adaptado interesantes piezas de hardware para acompañar las diferentes funciones de Android.
A principios de este año 2011, en febrero, se anunció la versión 3.0 de Android, llamada Honeycomb, que está optimizado para tabletas en lugar de teléfonos móviles. Esta novedad viene a poner sobre la mesa otra gama de posibilidades que tiene Android en dispositivos portátiles.
Cosas curiosas de Android
* Las versiones de Android aparte del número tienen un nombre de un postre en idioma inglés. En cada versión el postre elegido empieza con una letra distinta siguiendo un orden alfabético:
  • C: Cupcake (v1.5), magdalena glaseada.
  • D: Donut (v1.6), rosquilla.
  • E: Éclair (v2.0/v2.1), pastel francés conocido en España como pepito o canuto.
  • F: Froyo (v2.2), (abreviatura de «frozen yogurt») yogur helado.
  • G: Gingerbread (v2.3), pan de jengibre.
  • H: Honeycomb (v3.0/v3.1), panal de miel.
  • I: IceCream Sandwich (sin número aún), sandwich de helado.
* El logotipo de Android fue diseñado con la fuente Droid, hecha por Ascender Corporation.
* El verde es el color del robot Android que representa el sistema operativo. El color print es PMS 376C y color GBN en hexadecimal es #A4C639, como se específica en la Android Brand Guidelines que puedes consultar para ocupar en la personalización de algún logo para tu aplicación o proyecto.
* Debido a que existen muchas versiones a la fecha de Android, se tiene planeado el lanzamiento de Android Ice Cream Sandwich que tratará de unificar estos problemas de fragmentación que presenta la plataforma.
Si eres nuevo en Android espero que este post te haya ayudado a conocer algunas cosas, si ya usas o programas en Android, ¿qué otros datos curiosos conoces?

 
Android Community Network © 2012