La multitarea de Android al detalle

Android es un sistema operativo con multitarea, permite ejecutar varias aplicaciones al mismo tiempo. Los desarrolladores que vienen de una plataforma diferente puede encontrar un cambio llamativo al aplicar este concepto. A la hora de comenzar a desarrollar una aplicación de Android, es necesario comprender su funcionamiento para poder integrarlo lo mejor posible, aquí hablaremos del diseños, de las características, del uso y de su desarrollo, según lo explicado por la ingeniera de Google Dianne Hakborn:

Los dispositivos móviles tienen limitaciones técnicas que no tienen los sistemas de escritorio o en la web. En este artículo se explican las cuatro claves en las que se pensó para diseñar la multitarea en Android.

  • Se optó por utilizar una gestión de memoria basada en la «localidad temporal» (sí, algo así como en la memoria caché), es decir las aplicaciones no se llegan a cerrar cuando el usuario deja de utilizarlas, ya que la tendencia es  utilizar un número reducido de aplicaciones a lo largo del día.
  • Los dispositivos móviles no tienen el lujo de espacio de memoria swap, por lo que tienen límites muy restrictivos en la memoria.
  • Cambiar de una app a otra debe ser algo instantaneo, en un tiempo menor de 1 segundo para lanzar una nueva aplicación. El usuario tiende a usar pocas aplicaciones, por ejemplo cuando está viendo un video, recibe una llamada y después quiere continuar viendo el video. Retardos de más de un segundo pueden provocar situaciones de rechado del usuario.
  •  La API  disponible debe ser suficiente para cumplir con la famosa filosofía de Android  «todas las aplicaciones creadas son iguales» tanto las de «core» (nucleo) como la de «terceros» . Este fondo de los medios de reproducción de música, la sincronización de datos, navegación GPS, o el uso del vibrador se crean sin distinción.

Los dos primeros requisitos son algo contradictorios. Se quiso que el usuario no tuviese que preocuparse por cerrar la app, que pareciese que siempre estaban funcionando. Al mismo tiempo, los dispositivos móviles tienen límites estrictos en el uso de la memoria, de modo que un sistema se degrada, o incluso empiezan a fallar muy rápidamente, ya que necesita más memoria RAM . Un equipo Desktop por el contrario simplemente baja el ritmo de intercambio con el espacio swap. Estas consideraciones fueron clave para  la implementación de Android.

 

El ciclo de vida en Android

El error fundamental cuando hablamos de multitarea en Android es no diferenciar entre un proceso y aplicación. En Android no son entidades estrechamente unidas: varias aplicaciones pueden compartir procesos, o una aplicación puede hacer uso de múltiples procesos en función de sus necesidades.

El hecho de que se puede ver el proceso de una aplicación «en ejecución» no significa que la aplicación se está ejecutando o haciendo cualquier cosa. Puede ser simplemente que el sistema operativo así lo decida por distintas razones, y ha decidido tener alrededor por si lo necesita pronto. Del mismo modo, puede dejar desactivada una aplicación para un poco después volver a ella donde la dejó.

Una de las claves de cómo maneja las aplicaciones Android es saber qué hace cuando un proceso no se cierra limpiamente. Cuando el usuario sale de una aplicación, el proceso se mantiene en segundo plano preparado para volver a ejecutarse (por ejemplo la descarga de páginas web), si es necesario, y de manera inmediata puede volver a primer plano. Si no se queda sin memoria, todos los procesos se quedarán en suspensión.
Por supuesto, hay una cantidad limitada de memoria, y el sistema operativo debe decidir cuándo deshacerse de los procesos que no son necesarios. Esto es lo que se llama  «el ciclo de vida de Android«, el conjunto de reglas que deciden que proceso debe eliminarse. Estas reglas se basan tanto en la importancia de un proceso, según la experiencia actual del usuario, así como el uso que se le ha dado basado en estadísticas anteriores.

Una vez que Android determina la necesitad de eliminar un proceso, sólo hay que matarlo. El núcleo puede recuperar de inmediato todos los recursos necesarios para el nuevo proceso, sin necesitar que la aplicación este bien escrita y que responda correctamente a la orden de salir. El sistema operativo coge el control para que no se produzcan fallos de memoria.

Si un usuario reactiva una aplicación que había sido matada, Android tiene mecanismos para poner en marcha en el mismo estado anterior, para preservar el concepto de «todas las apps se están ejecutando todo el tiempo». Esto se hace mediante la restauración de los datos visibles por el usuario, las Activity (una activity es la pantalla que vemos en primer plano cuando ejecutamos una aplicación). Este último estado se genera cada vez que el usuario sale de la app, no cuando se le ha hecho kill, por lo que el núcleo más adelante puede libremente matarlo sin depender de la aplicación.

En cierto modo,el gestor de procesos puede ser visto como una forma de swap: los procesos de aplicación representan una cierta cantidad de memoria en uso, cuando queda poca memoria, algunos procesos pueden ser matados, y cuando esos procesos se necesitan otra vez, pueden ser iniciados desde su último estado guardado

Ejecución en Segundo plano

Hasta el momento, ya sabemos como se utilizan de forma implícita las apps en segundo plano. Esto está bien para completar descargas por ejemplo, pero ¿qué ocurre cuando necesitamos decirle al sistema operativo de forma explícita que se debe usar en background?. Intercambio de datos, gps, reproducción de música…

La app debe tener algunas formas de decirle a Android: » tío, sin llamar la atención» . Hay dos mecanismo esenciales para las aplicaciones en background representados por dos tipos de componentes que se pueden nombrar en su manifiesto (de este hablaremos otro día) explícitamente: broadcastreceivers y  services.

BroadcastReceiver

Un BroadcastReceiver permite una aplicación se ejecute, por un breve período de tiempo, en segundo plano como consecuencia de algo que está ocurriendo. Se puede utilizar en muchas maneras de construir instalaciones de mayor nivel: Por ejemplo LocationManager puede enviar un mensaje cuando detecta cambios interesantes en una determinada ubicación. Dado que la información sobre el receptor forma parte del manifiesto (manifest.xml) de una aplicación, Android puede encontrar y ejecutar la aplicación, incluso si no se está ejecutando y de forma muy eficiente.
Cuando se maneja una «recepción», la aplicación se da una cuota de tiempo para terminar. Si no se completa en ese tiempo, la aplicación se considera que se porta de forma inapropiada, y su proceso pasa la suspensión.

Es una forma que tiene la app de decirle al  sistema operativo: «Termino en 10 segundos«.

En definitiva, se utilizan cuando detecta un estímulo externo. En cualquier caso, no son apropiados para transmisiones de mucho tiempo, tales como las redes.

Servicios

Un servicio permite a una aplicación práctica a más largo se ejecutan operaciones en segundo plano. En realidad, hay un montón de otras funciones que proporcionan los servicios, pero  aquí su propósito fundamental es una aplicación para decir «tío, voy a estar aquí un buen rato, ya te aviso cuando termine» Una app controla a su servicio. Dice cuando se ejecuta y cuando se detiene.

Los servicios no proporcionan un buen modelo cliente-servidor, su uso es opcional. Al iniciar los servicios de una aplicación, Android, simplemente crea una instancia del componente en el proceso de la aplicación para ofrecer su contexto.
La gestión de procesos para los servicios es diferente a los BroadcastReceiver, ya que un número ilimitado de servicios puede solicitar que se ejecuta por un  tiempo desconocido. Puede que no haya suficiente memoria RAM para tener en ejecución el servicios, así que no hay garantías de que se complete con éxito.

Si hay poca RAM, los servicios será inmediatamente matados como procesos en segundo plano son. Sin embargo, en su caso, Android puede  reiniciar su proceso más tarde, cuando haya más memoria RAM disponible.

De forma coloquial se puede decir que los services siempre están en plan «llorica» diciendo «no quiero morir» y Android para no matarlo (en caso de necesidad de RAM) quiere ver que existe interactuación con el usuario, por ejemplo cuando se ejecuta música de fondo, Android sabe que el usuario conoce la existencia de ese proceso gracias a la barra de notificaciones que se puede ver el reproductor y por tanto no intentará matarlo.