Android lleva la cuenta atrás al extremo
Al desarrollar la función de cuenta regresiva, a menudo usamos CountDownTimer directamente por conveniencia o usamos Handler como retraso. Por supuesto, la encapsulación interna de CountDownTimer también usa Handler.
Si solo haces unas pocas cuentas regresivas o no necesitas una lógica de cuenta regresiva precisa, no importa. Por ejemplo, solo necesito hacer una cuenta regresiva durante 10 segundos o solicito una determinada interfaz en aproximadamente. 5 minutos.
Sin embargo, si se requiere una operación de cuenta regresiva precisa, por ejemplo, si el teléfono móvil envía un código de verificación durante 60 segundos, entonces habrá problemas al utilizar la solución de cuenta regresiva existente. Es posible que algunos amigos no se hayan dado cuenta de esto. Analicemos brevemente los problemas de cuenta regresiva existentes.
Este es probablemente el más utilizado porque es conveniente. Pero, de hecho, hay errores después de cada ronda de cuenta regresiva. Si ha visto el código fuente de CountDownTimer, sabrá que tiene operaciones de calibración internas. (El código fuente es muy simple y no lo analizaremos aquí)
Pero si ha probado cuidadosamente CountDownTimer, encontrará que incluso si realiza operaciones de calibración interna, habrá desviaciones en cada ronda. El tiempo total después de su última cuenta regresiva fue consistente con el tiempo cuando comenzó la cuenta regresiva.
¿Qué significa? Significa 1 segundo, 2.050 segundos, 3,1 segundos... Tal desviación en cada ronda hará que sea 10,95 segundos y 12 segundos luego si redondeas. directamente en la devolución de llamada faltará un segundo, pero en realidad no falta.
Este es solo uno de los problemas. No es necesario que lo muestres en función de su devolución de llamada, también puedes resolverlo usando una acumulación de plástico para mostrarlo tú mismo. Pero todavía tiene un problema. Existe la probabilidad de que el segundo salte directamente, es decir, 3 segundos, y la próxima vez sean 5 segundos. Este es el segundo de salto real, que es una devolución de llamada menos.
Los segundos saltantes pueden causar grandes problemas si lo usas directamente. Es posible que no lo encuentres durante la autoprueba. Cuando la aplicación está en línea, existe la probabilidad de que el usuario salte segundos, lo que será un problema. joda.
Si no haces tantas campanas y silbidos y usas Handler directamente para implementarlo, ¿qué problemas habrá?
Debido a que se implementa directamente usando el controlador y no hay operación de calibración, habrá un error de unos pocos milisegundos en cada ciclo. Aunque es mejor que el error de decenas de milisegundos de CountDownTimer. El error se acumulará en el caso de una cuenta regresiva con una base grande, lo que dará como resultado una diferencia de unos segundos entre el resultado final y el tiempo real. Cuanto mayor sea el tiempo, mayor será el error.
Lo mismo ocurre con. usando el temporizador directamente, excepto que el error en cada ronda es menor. El error es de solo 1 milisegundo en varias rondas, pero sin calibración, los errores aún se acumularán y cuanto más tiempo pase, mayor será el error.
Como no podemos usar el nativo directamente, creemos uno nosotros mismos.
Lo encapsulamos en base a Handler. Como se puede ver en lo anterior, es principalmente para resolver dos problemas, la calibración del tiempo y los segundos saltantes. Escribe tu propio CountDownTimer
La idea es obtener SystemClock.elapsedRealtime() una vez antes de que comience la cuenta regresiva, obtener SystemClock.elapsedRealtime() nuevamente después de la cuenta regresiva, restarlo para obtener el error y calibrarlo según el retraso. Luego use un bucle while para manejar la operación de omitir segundos. A diferencia del CountDownTimer nativo, si la cantidad de segundos omitidos aquí, se devolverán cuántas devoluciones de llamada.