Ciclo de vida de un servicio.

Ciclo de vida de un servicio

Es importante que recuerdes que un servicio tiene un ciclo de vida diferente a una actividad. A continuación, podemos ver un gráfico que ilustra el ciclo de vida de los servicios:

Figura 6: Ciclo de vida de los servicios.

Como acabamos de explicar existen dos tipos de servicios según como hayan sido creados. Las funciones de estos servicios son diferentes, y por lo tanto, también su ciclo de vida.

Si el servicio es iniciado mediante startService() el sistema comenzará creándolo y llamando a su método onCreate(). A continuación llamará a su método onStartCommand(Intent intent, int flags, int startId) [1] con los argumentos proporcionados por el cliente. El servicio continuará en ejecución hasta que sea invocado el método stopService() o stopSelf().

NOTA: Si se producen varias llamadas a startService() no supondrá la creación de varios servicios, aunque sí que se realizarán múltiples llamadas a onStartCommand(). No importa cuántas veces el servicio haya sido creado, parará con la primera invocación de stopService() o stopSelf(). Sin embargo, podemos utilizar el método stopSelf(int startId) para asegurarnos que el servicio no parará hasta que todas las llamadas hayan sido procesadas.

Cuando se inicia un servicio para realizar alguna tarea en segundo plano, el proceso donde se ejecuta podría ser eliminado ante una situación de baja memoria. Podemos configurar la forma en que el sistema reaccionará ante esta circunstancia según el valor que devolvamos en onStartCommand(). Existen dos modos principales: devolveremos START_STICKY si queremos que el sistema trate de crear de nuevo el servicio cuando disponga de memoria suficiente. Devolveremos START_NOT_STICKY si queremos que el servicio sea creado de nuevo solo cuando llegue una nueva solicitud de creación.

Teniendo en cuenta que los servicios pueden estar largo tiempo en ejecución, el ciclo de vida del proceso que contiene nuestro servicio es un asunto de gran importancia. Conviene aclarar que en situaciones donde el sistema necesite memoria conservar un servicio siempre será menos prioritario que la actividad visible en pantalla, aunque más prioritario que otras actividades en segundo plano. Dado que el número de actividades visibles es siempre reducido, un servicio solo será eliminado en situaciones de extrema necesidad de memoria. Por otra parte, si un cliente visible está conectado a un servicio, el servicio también será considerado como visible, siendo tan prioritario como el cliente. En el caso de un proceso que contenga varios componentes, por ejemplo una actividad y un servicio, su prioridad se obtiene como el máximo de sus componentes.

Podemos también utilizar bindService(Intent servicio, ServiceConnection conexion, int flags) para obtener una conexión persistente con un servicio. Si dicho servicio no está en ejecución, será creado (siempre que el flag BIND_AUTO_CREATE esté activo), llamándose al método onCreate(), pero no se llamará a onStartCommand(). En su lugar se llamará al método onBind(Intent intencion)  que ha de devolver al cliente un objeto IBinder a través del cual se podrá establecer una comunicación entre cliente y servicio. Esta comunicación se establece por medio de una interfaz escrita en AIDL, que permite el intercambio de objetos entre aplicaciones que corren en procesos separados. El servicio permanecerá en ejecución tanto tiempo como la conexión esté establecida, independientemente de que se mantenga o no la referencia al objeto IBinder.

También es posible diseñar un servicio que pueda ser arrancado de ambas formas (startService() y bindService()). Este servicio permanecerá activo se ha sido creado desde la aplicación que lo contiene o si recibe conexiones desde otras aplicaciones.

Todo servicio terminará llamando al método ancestro() cuando vaya a terminar de forma efectiva.


[1] En versiones del API inferiores a 2.0 el método llamado será onStart(). En versiones recientes se mantiene por razones de compatibilidad.