Temporizadores y trabajo de fondo. Es bien conocido gracias a Alice y …… autor: Ivana Tanova | Octubre de 2020

Gracias a Alice y Einstein, es bien sabido que el tiempo no es exacto, es relativo. En relación con nuestra propia realidad. Veamos cómo la realidad de nuestro mundo de la programación usa el tiempo.

Lo que vas a aprender:

  • Relojes de pared y relojes de CPU: cuál es la diferencia.
  • Por qué no deberías dormir en segundo plano. (Créeme, te lo explicaré)
  • Cómo implementar un temporizador confiable en Android.
  • Datos curiosos sobre el tiempo y el espacio

En el pasado profundo, la gente confiaba en los relojes de sombra. Espectáculos conen diferentes extremos de la Tierra hay algo diferente, ¿verdad? Nuestros relojes de pared hacen lo mismo, hay diferentes zonas horarias y se complica sobre la marcha. Lo mismo ocurre con los relojes utilizados en la programación, utilizan las mismas zonas horarias y una regla para recordar es: es importante OMS el tiempo te lo dice.

En la programación de relojes de «pared», el tiempo se mide en milisegundos desde el 1 de enero de 1970. Este año en particular se llama Época Unixy se utiliza en todos los sistemas Unix. Windows usa uno diferente. Es solo un punto aleatorio en el tiempo, un sistema que cuenta. Podemos decir que nuestros relojes de pared hacen lo mismo: cuentan los segundos transcurridos desde las 00 en punto. La principal diferencia es que cuando los segundos llegan a 86400, el tiempo se reinicia.

Volviendo a la programación de Java / Android, eso es exactamente lo que System.currentTimeMillis() devoluciones. Pero piense críticamente: ¿cómo podría medir la cantidad de milisegundos que han pasado? Debe saber cuál es la hora (fecha y hora) y la única entrada para estos datos es el usuario o la red telefónica. ¿Son confiables estas fuentes?

❗️¡Importante! No confíe en este tiempo si está esperando el final de la versión de prueba gratuita de la aplicación o el temporizador de sesión. El usuario puede piratearlo fácilmente simplemente ingresando la hora en el futuro. Entonces tienes que esperar unos años más por tu dinero.

Entonces, ¿por qué lo tenemos?

Utilice este reloj para:

Aplicación de calendario o despertador. Las aplicaciones que el tiempo dependen de la realidad del usuario. El usuario hará trampa si nos da el momento equivocado.

❌ No lo use para:

Medición de intervalo o tiempo transcurrido. Aplicaciones que dependen del tiempo transcurrido con precisión: temporizadores. Se basan en nuestra perspectiva de la realidad con base científica, en la que el mundo gira 86400 segundos y nada más ni menos.

Ahora estamos en un área familiar: la CPU es hardware, sabemos cómo funciona, podemos encenderlo y apagarlo, depende del rendimiento. ¡Cmmon todo el mundo tiene necesidades! El reloj de la CPU se refiere a milisegundos desde el inicio del sistema. En nuestro sistema cerrado, cuando la CPU está encendida, es nuestro amanecer y nuestro atardecer es cuando el dispositivo está apagado. Genial, tenemos una hora confiable que no se ve afectada por nuestros usuarios. ¡Casi! Hay dos implementaciones y debemos elegirlas con cuidado.

Este método mide el tiempo de la CPU. El problema con esto es que funciona mientras el procesador lo está haciendo. En los sistemas Android, la CPU ingresa al llamado sueño profundo cuando el modo de ahorro de batería está activado, el procesador está apagado, la pantalla está oscura o el dispositivo está esperando una entrada externa. En los dispositivos Android modernos con modo Doze y Standby, la aplicación entra en suspensión profunda cuando el ahorro de batería está activado y el dispositivo se desconecta del cable.

❗️¡Importante! No confíe en este temporizador para medir el tiempo que debe sobrevivir en el estado de fondo.

Utilice este reloj para:

  • Intervalo de tiempo que solo debería estar activo cuando la pantalla está encendida. Por ejemplo, tiene un botón que evita que se deshabiliten varios clics durante unos milisegundos después de un evento de clic de usuario. No te importa cuando la pantalla está apagada.

❌ No lo use para:

  • Temporizadores de fondo, alarmas, sesiones (si no reinicia la sesión, la pantalla está actualmente activa), recibir dinero, datos.
  • elapsedRealtime()

Recupere tiempo desde el inicio del sistema e incluya el sueño profundo. Este reloj está corriendo, incluso si la CPU no lo está. Esto se recomienda para el conteo general del tiempo. 🥳 🥳 🥳

Utilice este reloj para:

Mide el tiempo transcurrido incluso cuando tu aplicación está en segundo plano. Sesión.

❌ No lo use para:

Contando alarmas y fecha y hora.

Podemos pensar muy ingenuamente que no tenemos que preocuparnos por el tiempo en la pared y la CPU. Tenemos Thread.sleep una corrutina delay métodos. Claro … El núcleo de la programación básica es usar algo solo cuando se sabe cómo funciona. Así que veamos cómo funcionan estos métodos.

  • Thread.sleep()– Bajo el capó, este método usa uptimeMillis (). Una vez que su dispositivo ingrese al modo de suspensión, el tiempo restante se retrasará hasta que el dispositivo se active. Le da a este método 5 segundos y desea mostrar la barra de sonido después de exactamente 5 segundos, pero estos segundos no serán ciencia basada en el «mundo real», estarán «en pantalla» durante 5 segundos. Si han pasado 3 segundos y la CPU comienza a dormir durante 2 segundos, en el momento en que la CPU esté activa, esperará que su temporizador termine, pero lo que realmente sucede es que la CPU contará otros 2 segundos porque no sabe cuántos segundos durmió. No es estúpido, ¡simplemente no lo sabe!
  • Coroutine.delay() -La implementación aquí es un misterio para mí. El estado de la documentación es:

cómo se realiza el seguimiento del tiempo exactamente es el detalle de la implementación CoroutineDispatcher en contexto.

Encontré un artículo de Medium que afirma esto delay() se implementa a través de Handler.postDelayed() método. Esto suena razonable porque los controladores son la API básica para la programación asincrónica para Android.

  • Manipuladores: también utilizan manipuladores uptimeMillis() reloj.

Aquí está el código fuente del método Handler sendMessageDelayed:

public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

❗️ Así que no uses delay() para su mundo «real», el temporizador de tostadas francesas. Si el procesador se apaga, su cocina puede estar en llamas. 🔥

Un poco de drama ayuda con el aprendizaje 😉, así que ahora pasa un tiempo repitiendo:

retraso = fuego 🔥 🔥

Deberías considerar AlarmManager si realmente desea que este trabajo se realice en el momento exacto, pase lo que pase. Activa eventos incluso cuando el dispositivo está en reposo profundo o incluso cuando la aplicación no se está ejecutando. Tiene dos opciones: usar un reloj de pared o usar una CPU elapsedRealtime() relojes. B️Tenga cuidado: comenzando con API 19, debe usar el método setExact() de lo contrario, nuestra tostada francesa se habrá ido. 🔥

Entonces, si está preparando el desayuno, AlarmManager + ELAPSED_REALTIME + setExact () no es una mala elección.

Obviamente, AlarmManager no activa una alarma si el dispositivo se reinicia porque usa una CPU. Recuerda nuestra puesta de sol cuando la CPU está apagada, elapsedRealtime() no podría sobrevivir una vez que se apaga la CPU. El reloj se reinicia, es un nuevo día, uno nuevo.

Lo que dicen los chicos de Android en la documentación es:

Para operaciones de cronometraje comunes (ticks, tiempos de espera, etc.), el uso es más simple y mucho más eficiente Handler.

Así que volvamos a nuestros métodos de dormir y retrasar, probablemente use Handler. Úselos, pero reinicie el tiempo, cada vez que se enciende la pantalla, nunca se sabe si el procesador estaba en un sueño profundo.

elapsedRealtime()devuelve el tiempo desde que se inició el sistema e implica sueño profundo.

  • El estudio y la ciencia de medir el tiempo se llama relojería.
  • Antes de 1961 no había UTC y antes de 1958 no había ningún temporizador atómico extendido; en estas épocas, se utilizó alguna aproximación GMT (basada directamente en la rotación de la Tierra) en lugar de la línea de tiempo atómica.
  • Los entusiastas de Unix han celebrado «fiestas time_t» (pronunciado «fiestas del té en el tiempo») en el pasado para celebrar los valores significativos del número de tiempo Unix. Esta es una analogía directa con las celebraciones de Año Nuevo, que ocurren cuando el año cambia en muchos calendarios. El bilenio de Unix (número de tiempo de Unix 1000000000) se celebró el domingo 9 de septiembre de 2001 a las 01:46:40 UTC.
  • Los obeliscos egipcios probablemente se utilizaron como relojes de sombra. Las sombras en movimiento formaban una especie de reloj de sol, que permitía a los ciudadanos dividir el día en dos partes.
  • El reloj de cesio es tan preciso que se apaga solo un segundo después de correr 300 millones de años.

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/delay.html

https://developer.android.com/reference/android/os/SystemClock#uptimeMillis ()

https://medium.com/@f2016826/timers-vs-handlers-aeae5d3cb5a

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *