2. Estado del arte
2.3 Plataforma Android
2.3.3 Conceptos importantes
2.3.3.3 Ciclos de vida de los principales componentes de una aplicación
Hay cinco niveles diferentes en la jerarquía de importancia. En la Tabla 2. 1 se presentan todos los posibles procesos según dicha estructura [14].
Niveles de “importancia”
+
Foreground Process | Visible Process | Service Process Background Process-
Empty ProcessTabla 2. 1: Tipos de procesos según su nivel de prioridad
- Foreground Process: proceso de primer plano, necesario para la acción que desarrolla
el usuario en la actualidad. Coexistirán pocos de este tipo al mismo tiempo en el sistema. Serán eliminados como último recurso si la memoria es tan baja que ni ellos mismos pueden continuar ejecutándose.
- Visible Process: proceso que no tiene ningún componente en primer plano, pero sí
puede afectar a lo que el usuario está viendo por pantalla. Son procesos de una gran importancia, por lo que no serán eliminados a menos que sea necesario para que los foreground process puedan seguir ejecutándose.
- Service Process: proceso que ejecuta un service, por lo que no afecta directamente a
lo que se muestra por pantalla al usuario, pero sí ejecuta otras acciones requeridas por éste (reproducción de música o descarga de datos). El sistema siempre los mantendrá en ejecución a no ser que no haya memoria suficiente para que éstos funcionen junto con los dos procesos de niveles superiores.
- Background Process: proceso que ejecuta una activity no visible para el usuario en la
actualidad. Al no tener repercusión directa en las acciones que está desarrollando el usuario, el sistema puede eliminar estos procesos en cualquier momento que se necesite memoria para alguno de los tres tipos de procesos superiores. El criterio lo establece una lista según la cual, las últimos procesos con activities que hayan sido mostradas por pantalla serán los últimos en ser eliminados, lista LRU (Least Recently Used).
- Empty Process: proceso que no aloja ningún bloque de construcción activo. Su utilidad es mejorar el tiempo de arranque la próxima vez que el componente tenga que ejecutarse en él. El sistema los elimina a fin de equilibrar los recursos existentes de memoria.
El sistema de Android clasifica los procesos de forma que éstos se sitúen en el mayor nivel posible. Esta catalogación se basa siempre en la importancia que tengan los componentes activos presentes en el proceso.
2.3.3.3 Ciclos de vida de los principales componentes de una aplicación
Entender correctamente los ciclos de vida de los bloques de una aplicación es vital para garantizar que la aplicación proporcione una perfecta experiencia al usuario, a la vez que se gestionan adecuadamente los recursos del sistema [12]. Cada uno de los componentes básicos de las aplicaciones Android tiene su propio ciclo de vida. En este apartado se van a exponer los ciclos de vida de dos de los principales componentes: Activies y Services.
Ciclo de vida de una Activity
La gestión del ciclo de vida de las actividades mediante la implementación de los correspondientes métodos (Tabla 2. 2) es fundamental a la hora de lograr una aplicación robusta y flexible. El ciclo de vida de una activity depende directamente de su asociación con las demás y de la pila de actividades, “back stack” [14].
El estado de cada activity se determina según sea su posición en la pila de actividades, siendo ésta la estructura que recoge todas las actividades que están actualmente en ejecución según el criterio “último en llegar, primero en salir” [12].
Los estados viables en los que puede estar una actividad son los tres siguientes:
Activa (Resumed): la actividad se encuentra en un primer plano de la pantalla, está visible e interactuando con el usuario. En este estado la activity está en la parte más alta (primera posición) de la pila de actividades.
En pausa (Paused): la actividad está visible en la pantalla pero no es la que interactúa con el usuario. Es decir, otra actividad activa, parcialmente transparente o que no ocupa toda la pantalla, está por encima de ésta.
Parada (Stopped): la actividad se encuentra oculta por otras actividades, no está visible en el dispositivo.
El ciclo de vida de una actividad, es decir, los posibles caminos que una actividad puede recorrer entre los diferentes estados, se puede observar en la Figura 2. 8 [14].
2.3.3.3 Ciclos de vida de los principales componentes de una aplicación 47
Los métodos necesarios para manejar la transición de las actividades entre estados, y que en la Figura 2. 8 se representan en forma de rectángulos, se detallan en la Tabla 2. 2. Estos métodos: onCreate(), onRestart(), onStart(), onResume(), onPause(), onStop() y onDestroy(), son necesarios para definir el ciclo de vida completo de una actividad y controlar los bucles anidados que se forman (Figura 2. 9). Son tres los bucles que controlan y manejan los diferentes tiempos de vida:
Tiempo de vida total (entire lifetime): todo lo que le sucede a una actividad entre la llamada al método onCreate() y la llamada a onDestroy().
Tiempo de vida visible (visible lifetime): todo lo que le ocurre a una actividad entre la llamada al método onStart() y la llamada a onStop(). Durante este periodo de tiempo, el usuario puede ver la actividad en la pantalla e interactuar con ella o no, según el estado en el que se encuentre la actividad (activa o en pausa). Dentro del tiempo de vida total de la aplicación pueden existir múltiples visible lifetime, ya que las actividades pueden alternar entre estar oculto o visibles.
Tiempo de vida activo (foreground lifetime): tiempo de una actividad que transcurre entre la llamada al método onResume() y la llamada a onPause(). En este intervalo de tiempo, la actividad se sitúa en el primer plano de la pantalla mostrándose por delante de todas las demás actividades que puedan estar también dentro de la pantalla y es la que interactúa con el usuario.
Figura 2. 9: Tiempos de vida de una Activity
Método Descripción Eliminable? Próximo método onCreate() Se llama cuando se crea la actividad por
primera vez. No onStart()
onRestart() Llamado después de que se haya parado la
actividad y justo antes de volver a comenzarla. No onStart()
onStart() Se invoca cuando se quiere que la actividad sea
visible para el usuario. No
onResume() o onStop()
onResume() Actúa justo antes de que la actividad comience
a interactuar con el usuario. No onPause()
onPause() Método llamado cuando el sistema va a
ejecutar otra actividad en su estado activo. Si
onResume() o onStop()
onStop() Se llama a éste método cuando la actividad deja
de estar visible para el usuario. Si
onRestart() o onDestroy()
onDestroy()
Método invocado antes de que la actividad sea destruida. Será la última llamada que reciba la actividad.
Si -
Tabla 2. 2: Métodos del ciclo de vida de una Actividad
Activity is killable Activity- onRestart Activity - onCreate Activity - onDestroy Activity- onStart Activity- onStop Activity - onResume Activity - onPause
Tiempo de vida activo Tiempo de vida visible Tiempo de vida total
Ciclo de vida de un Service
Los servicios tienen un ciclo de vida mucho más sencillo que las actividades, un servicio comienza o se para. En este caso el control del ciclo de vida del service depende más de los desarrolladores de aplicaciones que del sistema Android. Por consiguiente, al desarrollar una aplicación Android se debe tener en cuenta que al ejecutar los servicios no se consuman recursos compartidos de manera innecesaria, como puedan ser la batería o la CPU [15].
Aunque este ciclo de vida sea simple, es de suma importancia prestar atención a cómo se crea y se destruye un servicio. La razón para ello es que un servicio puede estar ejecutándose en un segundo plano sin que el usuario sea consciente de ello.
El ciclo de vida de un servicio, desde que se crea hasta que se destruye (Figura 2. 10), puede tomar dos caminos distintos [14] según su inicialización:
Iniciado con startService: se crea el servicio a partir de la llamada al método
startService() desde otro componente. El servicio se ejecutará indefinidamente, hasta
que el servicio mismo llame a la función stopSelf(), o hasta que otro componente llame a
stopService(). Cuando esto pase, el service se parará y el sistema lo eliminará.
Iniciado con bindService: el cliente llama a la función bindService() para crear el servicio y se comunica con éste a través de la interfaz IBinder. Para cerrar la comunicación con el servicio, el cliente utiliza el método unbindService(). Muchos clientes pueden
conectarse a un mismo servicio, por lo que el sistema eliminará el servicio cuando todos los clientes hayan cortado su comunicación con él.
Estas dos opciones no son excluyentes, es decir, un cliente se puede conectar a un servicio que ya haya sido inicializado con startService(). Sin embargo, hasta que el cliente no se desligue del servicio, los métodos stopService() o stopSelf() no podrán
pararlo.