Con frecuencia, las apps necesitan hacer más de una cosa a la vez. Las APIs de Android proporcionan muchas formas diferentes de hacerlo. Elegir la opción correcta es muy importante; una opción puede ser adecuada para una situación, pero muy incorrecta para otra. Elegir las APIs incorrectas puede perjudicar el rendimiento de tu app o la eficiencia de los recursos, lo que puede agotar la batería y degradar el rendimiento del dispositivo del usuario en general. En algunos casos, elegir el enfoque incorrecto podría impedir que tu app aparezca en Play Store.
En este documento, se explican las diferentes opciones disponibles y se te ayuda a elegir la adecuada para tu situación.
Terminología
Algunos términos importantes relacionados con las tareas en segundo plano se pueden usar de varias maneras contradictorias. Por este motivo, es importante definir nuestros términos.
Si una app se ejecuta en segundo plano, el sistema le impone una serie de restricciones. (Por ejemplo, en la mayoría de los casos, una app en segundo plano no puede iniciar servicios en primer plano).
A los efectos de este documento, usaremos el término "tarea" para referirnos a una operación que realiza una app fuera de su flujo de trabajo principal. Para garantizar la alineación en la comprensión, dividimos esto en tres categorías principales de tipos de tareas: trabajo asíncrono, las APIs de programación de tareas y los servicios en primer plano.
Elige la opción correcta
En la mayoría de las situaciones, puedes determinar las APIs adecuadas para tu tarea si determinas la categoría (trabajo asíncrono, las APIs de programación de tareas o los servicios en primer plano) a la que pertenece la tarea.
Si aún no tienes certeza, puedes usar los diagramas de flujo que proporcionamos, que agregan más matices a la decisión. Cada una de estas opciones se describe con más detalle más adelante en este documento.
Existen dos situaciones principales que se deben tener en cuenta para las tareas en segundo plano:
- La tarea que inicia el usuario mientras la app está visible
- La tarea se inicia en respuesta a un evento, ya sea interno o externo.
Estas dos situaciones tienen sus propios árboles de decisión.
Trabajo asíncrono
En muchos casos, una app solo necesita realizar operaciones simultáneas mientras se ejecuta en primer plano. Por ejemplo, es posible que una app deba realizar un cálculo que lleve mucho tiempo. Si realizara el cálculo en el subproceso de IU, el usuario no podría interactuar con la app hasta que finalizara el cálculo, lo que podría generar un error de ANR. En un caso como este, la app debería usar una opción de trabajo asíncrono.
Entre las opciones comunes de trabajo asíncrono, se incluyen las corrutinas de Kotlin y los subprocesos de Java. Puedes encontrar más información en la documentación sobre el trabajo asíncrono. Es importante tener en cuenta que, a diferencia de las APIs de tareas en segundo plano, no se garantiza que el trabajo asíncrono finalice si la app deja de estar en una etapa del ciclo de vida válida (por ejemplo, si la app sale del primer plano).
APIs de programación de tareas
Las APIs de programación de tareas son una opción más flexible cuando necesitas realizar tareas que deben continuar incluso si el usuario sale de la app. En la mayoría de los casos, la mejor opción para ejecutar tareas en segundo plano es usar WorkManager, aunque, en algunos casos, puede ser apropiado usar la API de JobScheduler de la plataforma.
WorkManager es una biblioteca potente que te permite configurar trabajos simples o complejos según tus necesidades. Puedes usar WorkManager para programar tareas que se ejecuten en momentos específicos o especificar las condiciones en las que se debe ejecutar la tarea. Incluso puedes configurar cadenas de tareas, de modo que cada una se ejecute a su vez y pase sus resultados a la siguiente. Para comprender todas las opciones disponibles, lee la lista de funciones de WorkManager.
Estas son algunas de las situaciones más comunes para las tareas en segundo plano:
- Recuperar datos del servidor de forma periódica
- Recuperar datos de sensores (por ejemplo, datos del contador de pasos)
- Obtener datos de ubicación periódicos (se te debe otorgar el permiso
ACCESS_BACKGROUND_LOCATIONen Android 10 o versiones posteriores) - Subir contenido en función de un activador de contenido, como fotos creadas por la cámara
Servicios en primer plano
Los servicios en primer plano ofrecen una forma potente de ejecutar tareas de inmediato que no deberían interrumpirse. Sin embargo, los servicios en primer plano pueden generar una carga pesada en el dispositivo y, a veces, tienen implicaciones de privacidad y seguridad. Por estos motivos, el sistema impone muchas restricciones sobre cómo y cuándo las apps pueden usar los servicios en primer plano. Por ejemplo, un servicio en primer plano debe ser visible para el usuario y, en la mayoría de los casos, las apps no pueden iniciar servicios en primer plano cuando están en segundo plano. Para obtener más información, consulta la documentación de los servicios en primer plano.
Existen dos métodos para crear un servicio en primer plano. Puedes declarar tu propio Service y especificar que el servicio es un servicio en primer plano llamando a Service.startForeground(). Como alternativa, puedes
usar WorkManager para crear un servicio en primer plano, como se explica en Compatibilidad con
trabajadores de larga duración.
Sin embargo, es importante saber que un servicio en primer plano creado por WorkManager debe cumplir con las mismas restricciones que cualquier otro servicio en primer plano.
WorkManager solo proporciona algunas APIs de conveniencia para simplificar la creación de un servicio en primer plano.
APIs alternativas
El sistema ofrece APIs alternativas diseñadas para tener un mejor rendimiento en casos de uso más específicos. Si existe una API alternativa para tu caso de uso, te recomendamos que la uses en lugar de un servicio en primer plano, ya que debería ayudar a que tu app tenga un mejor rendimiento. En la documentación de los tipos de servicios en primer plano, se indica cuándo hay una buena API alternativa para usar en lugar de un tipo de servicio en primer plano en particular.
Estas son algunas de las situaciones más comunes en las que se usan APIs alternativas:
- Usar transferencias de datos iniciadas por el usuario para realizar cargas o descargas grandes, en lugar de crear un servicio en primer plano de sincronización de datos
- Usa el administrador de dispositivos complementarios para la vinculación por Bluetooth y la transferencia de datos, en lugar de usar un servicio en primer plano de dispositivo conectado.
- Usar el modo de pantalla en pantalla para reproducir videos, en lugar de crear un servicio en primer plano de reproducción de contenido multimedia
Tareas que inicia el usuario
Si una app necesita realizar tareas en segundo plano y el usuario inicia la operación mientras la app está visible, responde estas preguntas para encontrar el enfoque correcto.
¿La tarea debe seguir ejecutándose mientras la app está en segundo plano?
Si no es necesario que la tarea siga ejecutándose mientras la app está en segundo plano, debes usar el trabajo asíncrono. Hay varias opciones para realizar trabajos asíncronos. Lo importante es comprender que todas estas opciones dejan de funcionar si la app pasa a segundo plano. (También se detienen si se cierra la app). Por ejemplo, una app de redes sociales podría querer actualizar su feed de contenido, pero no necesitaría finalizar la operación si el usuario abandonara la pantalla.
¿Habrá una mala experiencia del usuario si la tarea se pospone o se interrumpe?
Es importante considerar si la experiencia del usuario se vería afectada si se pospone o cancela una tarea. Por ejemplo, si una app necesita actualizar sus recursos, es posible que el usuario no note si la operación se realiza de inmediato o en medio de la noche mientras se recarga el dispositivo. En casos como este, debes usar las opciones de trabajo en segundo plano.
¿Es una tarea breve y fundamental?
Si la tarea no se puede retrasar y se completará rápidamente, puedes usar un servicio en primer plano con el tipo shortService. Estos servicios son más fáciles de crear que otros servicios en primer plano y no requieren tantos permisos. Sin embargo, los servicios cortos deben completarse en un plazo de tres minutos.
¿Existe una API alternativa solo para este propósito?
Si la tarea no es invisible para el usuario, la solución correcta puede ser usar un servicio en primer plano. Estos servicios se ejecutan de forma continua una vez que se inician, por lo que son una buena opción cuando interrumpir la tarea generaría una mala experiencia del usuario. Por ejemplo, una app de seguimiento de entrenamiento podría usar sensores de ubicación para permitir que los usuarios registren su ruta de trote en un mapa. No querrás hacer esto con una opción de trabajo en segundo plano, ya que, si se pausa la tarea, el seguimiento se detendrá de inmediato. En una situación como esta, un servicio en primer plano es la opción más lógica.
Sin embargo, debido a que los servicios en primer plano pueden usar muchos recursos del dispositivo, el sistema impone muchas restricciones sobre cuándo y cómo se pueden usar. En muchos casos, en lugar de usar un servicio en primer plano, puedes usar una API alternativa que controle el trabajo por ti con menos problemas. Por ejemplo, si tu app necesita realizar una acción cuando el usuario llega a una ubicación determinada, la mejor opción es usar la API de geovallado en lugar de hacer un seguimiento de la ubicación del usuario con un servicio en primer plano.
Tareas en respuesta a un evento
A veces, una app necesita realizar tareas en segundo plano en respuesta a un activador, como los siguientes:
- Mensajes de transmisión
- Mensajes de Firebase Cloud Messaging (FCM)
- Alarmas que establece la app
Esto puede ser un activador externo (como un mensaje de FCM) o puede ser en respuesta a una alarma configurada por la app. Por ejemplo, un juego podría recibir un mensaje de FCM que le indique que actualice algunos recursos.
Si tienes la certeza de que la tarea finalizará en unos segundos, usa el trabajo asíncrono para realizarla. El sistema le dará a tu app unos segundos para realizar esas tareas, incluso si estaba en segundo plano.
Si la tarea tarda más de unos segundos, puede ser apropiado iniciar un servicio en primer plano para controlarla. De hecho, incluso si tu app se encuentra en segundo plano, es posible que se le permita iniciar un servicio en primer plano si el usuario activó la tarea y esta se encuentra dentro de una de las exenciones aprobadas de las restricciones de inicio en segundo plano. Por ejemplo, si una app recibe un mensaje de FCM de alta prioridad, se le permite iniciar un servicio en primer plano, incluso si está en segundo plano.
Si la tarea tardará más de unos segundos, usa las APIs de programación de tareas.