Creación de servicios de Android
En esta guía se de abordan los servicios de Xamarin.Android, que son componentes de Android que permiten realizar el trabajo sin una interfaz de usuario activa. Los servicios se usan con mucha frecuencia para las tareas que se realizan en segundo plano, como cálculos lentos, descarga de archivos, reproducción de música, entre otras. Explica los distintos escenarios para los que los servicios son adecuados y muestra cómo implementarlos tanto para realizar tareas en segundo plano de ejecución larga como para proporcionar una interfaz para llamadas a procedimientos remotos.
Introducción a Android Services
Las aplicaciones móviles no son como las aplicaciones de escritorio. Los escritorios tienen grandes cantidades de recursos, como el patrimonio de pantalla, la memoria, el espacio de almacenamiento y una fuente de alimentación conectada, y los dispositivos móviles no lo hacen. Estas restricciones obligan a las aplicaciones móviles a comportarse de manera diferente. Por ejemplo, la pantalla pequeña de un dispositivo móvil normalmente significa que solo una aplicación (es decir, actividad) está visible a la vez. Otras actividades se mueven al fondo y se insertan en un estado suspendido en el que no pueden realizar ningún trabajo. Sin embargo, el hecho de que una aplicación Android esté en segundo plano no significa que sea imposible que la aplicación siga funcionando.
Las aplicaciones De Android se han integrado por al menos uno de los cuatro componentes principales siguientes: Actividades,Receptores de difusión, Proveedores de contenido y Servicios. Las actividades son la piedra angular de muchas aplicaciones android excelentes porque proporcionan la interfaz de usuario que permite a un usuario interactuar con la aplicación. Sin embargo, cuando se trata de realizar un trabajo simultáneo o en segundo plano, las actividades no siempre son la mejor opción.
El mecanismo principal para el trabajo en segundo plano en Android es el servicio. Un servicio Android es un componente diseñado para realizar algún trabajo sin una interfaz de usuario. Un servicio puede descargar un archivo, reproducir música o aplicar un filtro a una imagen. Los servicios también se pueden usar para la comunicación entre procesos(IPC)entre aplicaciones Android. Por ejemplo, una aplicación Android podría usar el servicio music player que es de otra aplicación o una aplicación podría exponer datos (como la información de contacto de una persona) a otras aplicaciones a través de un servicio.
Los servicios y su capacidad para realizar trabajo en segundo plano son fundamentales para proporcionar una interfaz de usuario fluida y fluida. Todas las aplicaciones Android tienen un subproceso principal (también conocido como subproceso de interfaz de usuario)en el que se ejecutan las actividades. Para mantener la capacidad de respuesta del dispositivo, Android debe ser capaz de actualizar la interfaz de usuario a una velocidad de 60 fotogramas por segundo. Si una aplicación De Android realiza demasiado trabajo en el subproceso principal, Android quitará fotogramas, lo que a su vez hace que la interfaz de usuario parezca ser inejecosa (también conocida a veces como janky). Esto significa que cualquier trabajo realizado en el subproceso de interfaz de usuario debe completarse en el intervalo de tiempo entre dos fotogramas, aproximadamente 16 milisegundos (1 segundo cada 60 fotogramas).
Para solucionar este problema, un desarrollador puede usar subprocesos en una actividad para realizar algún trabajo que bloquearía la interfaz de usuario. Sin embargo, esto podría causar problemas. Es muy posible que Android destruya y vuelva a crear las varias instancias de la actividad. Sin embargo, Android no destruirá automáticamente los subprocesos, lo que podría provocar pérdidas de memoria. Un ejemplo principal de esto es cuando se gira el dispositivo: Android intentará destruir la instancia de la actividad y, a continuación, volverá a crear una nueva:

Se trata de una posible pérdida de memoria: el subproceso creado por la primera instancia de la actividad seguirá ejecutándose. Si el subproceso tiene una referencia a la primera instancia de la actividad, esto impedirá que Android recopile el objeto. Sin embargo, todavía se crea la segunda instancia de la actividad (que a su vez podría crear un subproceso). La rotación del dispositivo varias veces en una sucesión rápida puede agotar toda la RAM y forzar a Android a finalizar toda la aplicación para reclamar memoria.
Como regla general, si el trabajo que se va a realizar debe sobrevivir a una actividad, se debe crear un servicio para realizar ese trabajo. Sin embargo, si el trabajo solo es aplicable en el contexto de una actividad, la creación de un subproceso para realizar el trabajo podría ser más adecuada. Por ejemplo, la creación de una miniatura para una foto que se acaba de agregar a una aplicación de galería de fotos probablemente debería producirse en un servicio. Sin embargo, un subproceso puede ser más adecuado para reproducir algo de música que solo se debe escuchar mientras una actividad está en primer plano.
El trabajo en segundo plano se puede dividir en dos clasificaciones generales:
- Tarea de ejecución larga: se trata de un trabajo que se está ejecutando hasta que se detiene explícitamente. Un ejemplo de una tarea de larga duración es una aplicación que transmite música o que debe supervisar los datos recopilados de un sensor. Estas tareas deben ejecutarse aunque la aplicación no tenga ninguna interfaz de usuario visible.
- Tareas periódicas: (a veces denominada trabajo )Una tarea periódica tiene una duración relativamente corta (varios segundos) y se ejecuta según una programación (es decir, una vez al día durante una semana o quizás una sola vez en los próximos 60 segundos). Un ejemplo de esto es descargar un archivo de Internet o generar una miniatura para una imagen.
Hay cuatro tipos diferentes de servicios de Android:
Servicio enlazado: un servicio enlazado es un servicio que tiene algún otro componente (normalmente una actividad) enlazado a él. Un servicio enlazado proporciona una interfaz que permite que el componente enlazado y el servicio interactúen entre sí. Una vez que no haya más clientes enlazados al servicio, Android apagará el servicio.
IntentService: es una subclase especializada de la clase que simplifica la creación y el usoIntentServiceServicedel servicio. EstáIntentServicediseñado para controlar llamadas autónomas individuales. A diferencia de un servicio, que puede controlar simultáneamente varias llamadas, un es más parecido a un procesador de cola de trabajo: el trabajo se pone en cola y procesa cada trabajo de uno en uno en un único subproceso deIntentServiceIntentServiceIntentServicetrabajo. Normalmente, noIntentServiceestá enlazado a una actividad o un fragmento.Servicio iniciado: un servicio iniciado es un servicio iniciado por algún otro componente de Android (como una actividad) y se ejecuta continuamente en segundo plano hasta que algo indica explícitamente al servicio que se detenga. A diferencia de un servicio enlazado, un servicio iniciado no tiene ningún cliente enlazado directamente a él. Por esta razón, es importante diseñar los servicios iniciados para que se puedan reiniciar correctamente según sea necesario.
Servicio híbrido: un servicio híbrido es un servicio que tiene las características de un servicio iniciado y un servicio enlazado. Un servicio híbrido se puede iniciar cuando un componente se enlaza a él o puede iniciarse mediante algún evento. Un componente de cliente puede o no estar enlazado al servicio híbrido. Un servicio híbrido seguirá ejecutándose hasta que se le indica explícitamente que se detenga o hasta que no haya más clientes enlazados a él.
El tipo de servicio que se va a usar depende mucho de los requisitos de la aplicación. Como regla general, un servicio o un servicio enlazado son suficientes para la mayoría de las tareas que debe realizar una aplicación Android, por lo que se debe dar preferencia a uno de esos dos tipos IntentService de servicios. Una es una buena opción para las tareas de "un solo uso", como descargar un archivo, mientras que un servicio enlazado sería adecuado cuando se requieren interacciones frecuentes con una actividad IntentService o fragmento.
Aunque la mayoría de los servicios se ejecutan en segundo plano, hay una subcategoría especial conocida como servicio en primer plano. Se trata de un servicio que tiene una prioridad más alta (en comparación con un servicio normal) para realizar algún trabajo para el usuario (como reproducir música).
También es posible ejecutar un servicio en su propio proceso en el mismo dispositivo, lo que a veces se conoce como servicio remoto o servicio fuera de proceso. Esto requiere más esfuerzo para crear, pero puede ser útil cuando una aplicación necesita compartir funcionalidad con otras aplicaciones y, en algunos casos, puede mejorar la experiencia del usuario de una aplicación.
Límites de ejecución en segundo plano en Android 8.0
A partir de Android 8.0 (nivel de API 26), una aplicación Android ya no tiene la capacidad de ejecutarse libremente en segundo plano. Cuando está en primer plano, una aplicación puede iniciar y ejecutar servicios sin restricciones. Cuando una aplicación pasa a segundo plano, Android le concederá una cierta cantidad de tiempo para iniciar y usar servicios. Una vez transcurrido ese tiempo, la aplicación ya no puede iniciar ningún servicio y se finalizará cualquier servicio que se haya iniciado. En este momento no es posible que la aplicación realice ningún trabajo. Android considera que una aplicación está en primer plano si se cumple una de las condiciones siguientes:
- Hay una actividad visible (iniciada o en pausa).
- La aplicación ha iniciado un servicio en primer plano.
- Otra aplicación está en primer plano y usa componentes de una aplicación que, de lo contrario, estarían en segundo plano. Un ejemplo de esto es si la aplicación A, que está en primer plano, está enlazada a un servicio proporcionado por la aplicación B. La aplicación B también se consideraría en primer plano y Android no terminaría por estar en segundo plano.
Hay algunas situaciones en las que, aunque una aplicación está en segundo plano, Android reactivará la aplicación y relajará estas restricciones durante unos minutos, lo que permite que la aplicación realice algún trabajo:
- La aplicación recibe un mensaje en la nube de Firebase de alta prioridad.
- La aplicación recibe una difusión.
- La aplicación recibe y ejecuta un
PendingIntenten respuesta a una notificación.
Es posible que las aplicaciones existentes de Xamarin.Android tengan que cambiar la forma en que realizan el trabajo en segundo plano para evitar cualquier problema que pueda surgir en Android 8.0. Estas son algunas alternativas prácticas a un servicio Android:
- Programar el trabajo para que se ejecute en segundo plano mediante Android Job Scheduler o Firebase Job Dispatcher: estas dos bibliotecas proporcionan un marco para que las aplicaciones segregan el trabajo en segundo plano en trabajos ,una unidad discreta de trabajo. A continuación, las aplicaciones pueden programar el trabajo con el sistema operativo junto con algunos criterios sobre cuándo se puede ejecutar el trabajo.
- Iniciar el servicio en primer plano: un servicio en primer plano es útil cuando la aplicación debe realizar alguna tarea en segundo plano y es posible que el usuario tenga que interactuar periódicamente con esa tarea. El servicio en primer plano mostrará una notificación persistente para que el usuario sea consciente de que la aplicación ejecuta una tarea en segundo plano y también proporciona una manera de supervisar o interactuar con la tarea. Un ejemplo de esto sería una aplicación de podcasts que reproduce un podcast al usuario o quizás descarga un episodio de podcasts para que se pueda disfrutar más adelante.
- Usar un mensaje de Firebase Cloud Message (FCM) de alta prioridad: cuando Android recibe una FCM de alta prioridad para una aplicación, permitirá que esa aplicación ejecute servicios en segundo plano durante un breve período de tiempo. Esta sería una buena alternativa a tener un servicio en segundo plano que sondee una aplicación en segundo plano.
- Aplazar el trabajo cuando la aplicación entra en primer plano: si ninguna de las soluciones anteriores es viable, las aplicaciones deben desarrollar su propia manera de pausar y reanudar el trabajo cuando la aplicación llega al primer plano.