domingo, 4 de marzo de 2012

Ciclo de Vida de Aplicaciones y actividades en Android


A diferencia de la mayoría de los ambientes de trabajo, las aplicaciones de Android no pueden controlar su ciclo de vida. En lugar de eso, deben esperar eventos que cambien el estado de la aplicación, y reaccionar según el caso, incluyendo el caso de ser cerradas prematuramente.
Por defecto, cada aplicación de Android corre en su propio proceso (Aún que es posible forzar varias aplicaciones a compartir el mismo proceso, usando el atributo android:process dentro del Manifest). Cada aplicación corre su propia instancia de Dalvik, y la memoria y el manejo de recursos se manejan exclusivamente por Android.
Debido a los pocos recursos con los que los dispositivos de Android suelen contar, el Run Time maneja agresivamente los recursos, matando aplicaciones de baja prioridad para darle recursos a los que lo requieren (Generalmente, la aplicación con la que el usuario interactúa directamente)
El hecho de que cada aplicación se ejecuta en su propio proceso aporta beneficios en cuestiones básicas como seguridad, gestión de memoria, o la ocupación de la CPU del dispositivo móvil. Android se ocupa de lanzar y parar todos estos procesos, gestionar su ejecución y decidir qué hacer en función de los recursos disponibles y de las órdenes dadas por el usuario. 

   El usuario desconoce este comportamiento de Android. Simplemente es consciente de que mediante un simple clic pasa de una a otra aplicación y puede volver a cualquiera de ellas en el momento que lo desee. No debe preocuparse sobre cuál es la aplicación que realmente está activa, cuánta memoria está consumiendo, ni si existen o no recursos suficientes para abrir una aplicación adicional. Todo eso son tareas propias del sistema operativo. 

   Android lanza tantos procesos como permitan los recursos del dispositivo. Cada proceso, correspondiente a una aplicación, estará formado por una o varias actividades independientes (componentes Activity) de esa aplicación. Cuando el usuario navega de una actividad a otra, o abre una nueva aplicación, el sistema duerme dicho proceso y realiza una copia de su estado para poder recuperarlo más tarde. El proceso y la actividad siguen existiendo en el sistema, pero están dormidos y su estado ha sido guardado. Es entonces cuando crea, o despierta si ya existe, el proceso para la aplicación que debe ser lanzada, asumiendo que existan recursos para ello.
   Cada uno de los componentes básicos de Android tiene un ciclo de vida bien definido; esto implica que el desarrollador puede controlar en cada momento en qué estado se encuentra dicho componente, pudiendo así programar las acciones que mejor convengan. El componente Activity, probablemente el más importante.
Ciclo de vida de una actividad
  • onCreate(), onDestroy(): Abarcan todo el ciclo de vida. Cada uno de estos métodos representan el principio y el fin de la actividad.
  • onStart(), onStop():  Representan la parte visible del ciclo de vida. Desde onStart() hasta onStop(), la actividad será visible para el usuario, aunque es posible que no tenga el foco de acción por existir otras actividades superpuestas con las que el usuario está interactuando. Pueden ser llamados múltiples veces.
  • onResume(), onPause(): Delimitan la parte útil del ciclo de vida. Desde onResume() hasta onPause(), la actividad no sólo es visible, sino que además tiene el foco de la acción y el usuario puede interactuar con ella. 
   Tal y como se ve en el diagrama de la figura anterior, el proceso que mantiene a esta Activity puede ser eliminado cuando se encuentra en onPause() o en onStop(), es decir, cuando no tiene el foco de la aplicación. Android nunca elimina procesos con los que el usuario está interactuando en ese momento. Una vez se elimina el proceso, el usuario desconoce dicha situación y puede incluso volver atrás y querer usarlo de nuevo. Entonces el proceso se restaura gracias a una copia y vuelve a estar activo como si no hubiera sido eliminado. Además, la Activity puede haber estado en segundo plano, invisible, y entonces es despertada pasando por el estado onRestart().

   Pero, ¿qué ocurre en realidad cuando no existen recursos suficientes? Obviamente, los recursos son siempre limitados, más aun cuando se está hablando de dispositivos móviles. En el momento en el que Android detecta que no hay los recursos necesarios para poder lanzar una nueva aplicación, analiza los procesos existentes en ese momento y elimina los procesos que sean menos prioritarios para poder liberar sus recursos.

   Cuando el usuario regresa a una actividad que está dormida, el sistema simplemente la despierta. En este caso, no es necesario recuperar el estado guardado porque el proceso todavía existe y mantiene el mismo estado. Sin embargo, cuando el usuario quiere regresar a una aplicación cuyo proceso ya no existe porque se necesitaba liberar sus recursos, Android lo crea de nuevo y utiliza el estado previamente guardado para poder restaurar una copia fresca del mismo. Como se ya ha explicado, el usuario no percibe esta situación ni conoce si el proceso ha sido eliminado o está dormido.

Prioridad y Procesos

El orden en que los procesos se eliminan se determina por la prioridad de las aplicaciones en uso. Su prioridad se define por el componente de mayor prioridad. Si dos aplicaciones empatan, el proceso con menor prioridad por mas tiempo será eliminado primero.
La prioridad también se define en base a dependencias de otros procesos: Si una aplicación depende de un Service o Content Provider de otra aplicación, la aplicación secundaria tendrá por lo menos la misma prioridad que la aplicación que la necesita.
Por último, todas las aplicaciones de Android se quedan corriendo y en la memoria hasta que los recursos son requeridos por otras aplicaciones.
Los Procesos Activos son aquellos con los que el usuario interactúa. Android tiene como prioridad mostrar una interfáz que responde al usuario. Generalmente son pocos los procesos con esta prioridad, y solo serán eliminados como último recurso.
Entre los procesos activos tenemos:
·         Activities que estan visibles e interactuando con el usuario.
·         Broadcast Receivers ejecutando onReceive.
·         Services ejecutando onStart, onCreate o onDestroy.
·         Services que han sido marcados como que corren de primera instancia. 
Los Procesos Visibles son visibles, pero inactivos. Estos son poco comunes, suceden cuando una Activity se lanza, y no cubre toda la pantalla o es transparente y muestra la aplicación de fondo. Android solo eliminaría procesos en este estado en casos extremos.
Los Procesos de Servicio son Services que han iniciado, no tienen una interfaz visible, y estan actualmente corriendo de fondo. Son importantes, y solo serán eliminados en el caso que Android requiera recursos para el proceso activo.
Los Procesos de Background no son visibles, y tampoco estan corriendo actualmente. Generalmente hay muchos procesos de fondo que Android matará segun las reglas que tiene definidas.
Los Procesos Vacios son cascarones que permanecen en la memoria aún despues de haber sido cerradas. Permanecen en este estado para agilizar el cargar la aplicación si se vuelve a abrir, y son eliminados en cuanto los recursos se requieren.

1 comentario: