El uso de la radio inalámbrica para transferir datos es quizás una de las fuentes más importantes de consumo de la batería de tu app. Con el fin de minimizar el consumo de la batería asociado con la actividad de red, es esencial que comprendas cómo el modelo de conectividad afecta al hardware subyacente de la radio.
En esta sección, se presenta la máquina de estado de radio inalámbrica y se explica cómo interactúa con ella el modelo de conectividad de tu app. Luego, ofrece varias técnicas que, si se siguen, ayudarán a minimizar el efecto del consumo de datos de tu app en la batería.
Máquina de estado de radio
La radio inalámbrica del dispositivo de tu usuario tiene funciones integradas de ahorro de energía que ayudan a minimizar la cantidad de batería que consume. Cuando está completamente activa, la radio inalámbrica consume mucha energía, pero cuando está inactiva o en espera, consume muy poca.
Un factor importante que debes recordar es que la radio no puede pasar del modo de espera al modo completamente activo de forma instantánea. Hay un período de latencia asociado con el "encendido" de la radio. Por lo tanto, la batería pasa de estados de mayor energía a estados de menor energía lentamente para conservar la energía cuando no está en uso, mientras intenta minimizar la latencia asociada con el "encendido" de la radio.
La máquina de estado de una radio de red 3G típica consta de tres estados de energía:
- Energía completa: Se utiliza cuando una conexión está activa, lo que permite que el dispositivo transfiera datos a la máxima velocidad posible.
- Bajo consumo: Es un estado intermedio que reduce el consumo de batería en alrededor de un 50%.
- En espera: Es el estado de consumo mínimo de energía durante el cual no hay ninguna conexión de red activa.
Si bien los estados "energía baja" y "en espera" consumen mucha menos batería, también presentan una latencia significativa para las solicitudes de red. Volver a la potencia máxima desde el estado bajo tarda alrededor de 1.5 segundos, y pasar del modo de espera a la potencia máxima puede tardar más de 2 segundos.
Para minimizar la latencia, la máquina de estado usa un retraso para posponer la transición a estados de energía más baja. En la figura 1, se muestran los tiempos de AT&T para una radio 3G típica.
Figura 1: Máquina de estado de radio inalámbrica 3G convencional
La máquina de estado de radio de cada dispositivo, en particular la demora de transición asociada ("tiempo de cola") y la latencia de inicio, variará según la tecnología de radio inalámbrica empleada (3G, LTE, 5G, etc.) y la red del operador en la que funciona el dispositivo la define y configura.
En esta página, se describe una máquina de estado representativa para una radio inalámbrica 3G típica, según los datos proporcionados por AT&T. Sin embargo, los principios generales y las prácticas recomendadas resultantes se aplican a todas las implementaciones de radio inalámbrica.
Este enfoque es especialmente eficaz para la navegación web típica en dispositivos móviles, ya que evita la latencia no deseada mientras los usuarios navegan por la Web. El tiempo de cola relativamente bajo también garantiza que, una vez que finaliza una sesión de navegación, la radio pueda pasar a un estado de menor consumo de energía.
Lamentablemente, este enfoque puede generar apps ineficientes en sistemas operativos de smartphones modernos, como Android, en los que las apps se ejecutan tanto en primer plano (donde la latencia es importante) como en segundo plano (donde se debe priorizar la duración de la batería).
Qué tipo de impacto tienen las apps en la máquina de estado de radio
Cada vez que creas una nueva conexión de red, la radio pasa al estado de energía completa. En el caso de la máquina de estado de radio 3G típica que se describió anteriormente, permanecerá con la máxima potencia durante la transferencia, más 5 segundos adicionales de tiempo de cola, seguidos de 12 segundos en el estado de bajo consumo. Por lo tanto, en un dispositivo 3G típico, cada sesión de transferencia de datos hará que la radio consuma energía durante al menos 18 segundos.
En la práctica, esto significa que una app que realiza una transferencia de datos de un segundo, tres veces por minuto, mantendrá la radio inalámbrica activa de forma perpetua, lo que la devolverá a un estado de alta potencia justo cuando esté entrando en el modo en espera.
Figura 2: Uso relativo de la energía de radio inalámbrica para una transferencia de un segundo que se ejecuta tres veces por minuto La cifra excluye la latencia de "encendido" entre ejecuciones.
En comparación, si la misma app agrupara sus transferencias de datos y ejecutara una sola transferencia de tres segundos por minuto, la radio se mantendría en el estado de alta potencia durante un total de solo 20 segundos por minuto. Esto permitiría que la radio esté en espera durante 40 segundos de cada minuto, lo que generaría una reducción significativa en el consumo de batería.
Figura 3: Uso relativo de la energía de radio inalámbrica para transferencias de tres segundos que se ejecutan una vez por minuto.
Técnicas de optimización
Ahora que comprendes cómo el acceso a la red afecta la duración de la batería, hablemos de algunas cosas que puedes hacer para reducir el agotamiento de la batería y, al mismo tiempo, brindar una experiencia del usuario rápida y fluida.
Agrupa las transferencias de datos
Como se indicó en la sección anterior, agrupar las transferencias de datos para que transfieras más datos con menos frecuencia es una de las mejores maneras de mejorar la eficiencia de la batería.
Por supuesto, esto no siempre es posible si tu app necesita recibir o enviar datos de inmediato en respuesta a una acción del usuario. Para mitigar este problema, puedes anticipar y recuperar datos con anticipación. Otras situaciones, como el envío de registros o estadísticas a un servidor y otras transferencias de datos no urgentes iniciadas por la app, se prestan muy bien para el procesamiento por lotes y la agrupación. Consulta Optimiza las tareas iniciadas por la app para obtener sugerencias sobre cómo programar transferencias de red en segundo plano.
Datos de recuperación previa
La carga previa de datos es otra forma eficaz de reducir la cantidad de sesiones de transferencia de datos independientes que ejecuta tu app. Con la carga previa, cuando el usuario realiza una acción en tu app, esta anticipa los datos que probablemente se necesitarán para la próxima serie de acciones del usuario y los obtiene todos juntos en una sola conexión y a máxima capacidad.
Mediante la carga de las transferencias, se reduce la cantidad de activaciones de radio necesarias para descargar los datos. Como resultado, no solo conservas la duración de la batería, sino que también mejoras la latencia, disminuyes el ancho de banda requerido y reduces los tiempos de descarga.
La carga previa también mejora la experiencia del usuario, ya que minimiza la latencia en la app que se produce cuando se espera a que se completen las descargas antes de realizar una acción o ver datos.
Aquí puedes ver un ejemplo práctico.
Lector de noticias
Muchas apps de noticias intentan reducir el ancho de banda descargando titulares solo después de que se ha seleccionado una categoría, artículos completos solo cuando el usuario quiere leerlos y miniaturas cuando se desplaza la vista.
Con este enfoque, la radio se ve obligada a permanecer activa durante la mayor parte de la sesión de lectura de noticias de los usuarios, mientras se desplazan por los titulares, cambian de categoría y leen artículos. Además, el cambio constante entre los estados de energía genera una latencia significativa cuando se cambian las categorías o se leen los artículos.
Un mejor enfoque es recuperar previamente una cantidad razonable de datos durante el inicio, comenzando con el primer conjunto de titulares de noticias y miniaturas (lo que garantiza un tiempo de inicio de baja latencia) y continuando con los titulares y las miniaturas restantes, así como el texto de cada artículo disponible, al menos, en la lista de titulares principal.
Otra alternativa es precargar todos los titulares; miniaturas; textos del artículo; y, posiblemente, imágenes completas del artículo (en general, en segundo plano y en un horario predeterminado). Con este enfoque, se corre el riesgo de dedicar una gran cantidad de ancho de banda y duración de la batería a la descarga de contenido que nunca se usará, por lo que debe implementarse con precaución.
Consideraciones adicionales
Si bien la carga previa de datos tiene muchos beneficios, si se usa de forma demasiado agresiva, también presenta el riesgo de aumentar el consumo de batería y el uso del ancho de banda, así como la cuota de descarga, ya que se descargan datos que no se usan. También es importante asegurarse de que la carga previa no retrase el inicio de la aplicación mientras esta espera a que se complete la carga previa. En términos prácticos, esto podría significar procesar datos de forma progresiva o iniciar transferencias consecutivas priorizadas de modo que los datos necesarios para el inicio de la aplicación se descarguen y procesen primero.
La agresividad con la que se realiza la carga previa de datos depende del tamaño de los datos que se descargan y de la probabilidad de que se usen. Como guía aproximada, según la máquina de estado descrita antes, para los datos que tienen un 50% de probabilidades de usarse en la sesión actual del usuario, puedes realizar una carga previa de alrededor de 6 segundos (aproximadamente 1 o 2 megabytes) antes de que el costo potencial de descargar datos no utilizados coincida con el ahorro potencial de no descargar esos datos, para empezar.
En términos generales, te recomendamos precargar los datos de modo que solo tengas que iniciar otra descarga cada 2 a 5 minutos y en el orden de 1 a 5 megabytes.
Según este principio, las descargas grandes, como los archivos de video, deben descargarse en fragmentos a intervalos regulares (cada 2 a 5 minutos), de modo que se recuperen previamente solo los datos de video que probablemente se verán en los próximos minutos.
Una solución es programar la descarga completa para que se produzca solo cuando haya conexión a Wi-Fi y, posiblemente, solo cuando el dispositivo se esté cargando. La API de WorkManager admite exactamente este caso de uso, lo que te permite restringir el trabajo en segundo plano hasta que el dispositivo cumpla con los criterios especificados por el desarrollador, como la carga y la conexión a Wi-Fi.
Verifica la conectividad antes de realizar solicitudes
La búsqueda de una señal de red móvil es una de las operaciones que más energía consume en un dispositivo móvil. Una práctica recomendada para las solicitudes iniciadas por el usuario es verificar primero si hay una conexión con ConnectivityManager, como se muestra en Cómo supervisar el estado de conectividad y la medición de la conexión.
Si no hay red, la app puede ahorrar batería, ya que no fuerza a la radio móvil a realizar una búsqueda. Luego, la solicitud se puede programar y realizar en un lote con otras solicitudes cuando se establece una conexión.
Conexiones de grupo
Otra estrategia que puede ayudar, además de la agrupación por lotes y la carga previa, es agrupar las conexiones de red de tu app.
Por lo general, es más eficiente reutilizar las conexiones de red existentes que iniciar nuevas. La reutilización de conexiones también permite que la red reaccione de manera más inteligente a la congestión y a los problemas relacionados con los datos de red.
HttpURLConnection y la mayoría de los clientes HTTP, como OkHttp, habilitan la agrupación de conexiones de forma predeterminada y reutilizan la misma conexión para varias solicitudes.
Repaso y próximos pasos
En esta sección, aprendiste mucho sobre la radio inalámbrica y algunas estrategias que puedes aplicar de forma general para proporcionar una experiencia del usuario rápida y responsiva, a la vez que reduces el agotamiento de la batería.
En la siguiente sección, analizaremos en detalle tres tipos distintos de interacciones de red comunes para la mayoría de las apps. Aprenderás sobre los controladores de cada uno de estos tipos, así como las técnicas y las APIs modernas para administrar estas interacciones de manera eficiente.