偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

把倒計(jì)時(shí)做到極致

開(kāi)發(fā) 開(kāi)發(fā)工具
倒計(jì)時(shí)這種,每秒更新 UI 的需求,應(yīng)該算是比較常見(jiàn)的了。最常見(jiàn)的場(chǎng)景,就是驗(yàn)證碼發(fā)送超時(shí)重試的邏輯,這個(gè)邏輯中需要一個(gè)倒計(jì)時(shí)的邏輯去每秒修改 UI ,讓倒計(jì)時(shí)做到用戶(hù)可感知。

[[197506]]

 一、前言

倒計(jì)時(shí)這種,每秒更新 UI 的需求,應(yīng)該算是比較常見(jiàn)的了。最常見(jiàn)的場(chǎng)景,就是驗(yàn)證碼發(fā)送超時(shí)重試的邏輯,這個(gè)邏輯中需要一個(gè)倒計(jì)時(shí)的邏輯去每秒修改 UI ,讓倒計(jì)時(shí)做到用戶(hù)可感知。

那么倒計(jì)時(shí)的邏輯,需要如何做到***?

一個(gè)倒計(jì)時(shí),最少要有兩個(gè)要求:準(zhǔn)、穩(wěn)。

準(zhǔn)就是說(shuō),一個(gè) 2 分鐘的倒計(jì)時(shí),就應(yīng)該執(zhí)行兩分鐘,穩(wěn)的意思就是說(shuō),每次同步 UI 的更新,都是差不多間隔 1s。

二、實(shí)現(xiàn)思路

1、每次延遲 1s 通知 UI 更新

倒計(jì)時(shí)說(shuō)白了就是一個(gè)間隔固定時(shí)間去做一件固定任務(wù),這樣的功能,最簡(jiǎn)單的就是使用 Handler.postDelayed() 去間隔執(zhí)行。

那么我們寫(xiě)一個(gè) CountdownUtils 的類(lèi),先看看它的結(jié)構(gòu)。

可以看到,它是基于一個(gè) Handler 來(lái)做延遲的。這個(gè)邏輯非常的簡(jiǎn)單,直接上代碼了。

使用起來(lái)也非常的簡(jiǎn)單,傳遞進(jìn)去 2 分鐘的時(shí)長(zhǎng)。

  1. new CountdownUtils(120).start() 

看看 Log 輸出的結(jié)果,

從 Log 上看,確實(shí)是完成了一個(gè)倒計(jì)時(shí)的功能,一秒一秒一直到 0 ,但是這里為了觀察準(zhǔn)不準(zhǔn),對(duì)倒計(jì)時(shí)執(zhí)行的完整時(shí)間做了一個(gè)間隔記錄,看到問(wèn)題了嗎?一個(gè) 120s 的倒計(jì)時(shí),卻執(zhí)行了124s 左右。

這個(gè)問(wèn)題實(shí)際上是因?yàn)?Handler.postDelayed() 的間隔時(shí)長(zhǎng),并不是準(zhǔn)確的間隔指定的時(shí)長(zhǎng),具體什么時(shí)候執(zhí)行,實(shí)際上是看線程的調(diào)度的。這種總時(shí)長(zhǎng)差異的問(wèn)題,換了 Timer 什么的去實(shí)現(xiàn)也是無(wú)法解決的。

這個(gè)問(wèn)題,在一些驗(yàn)證碼倒計(jì)時(shí)的場(chǎng)景下,沒(méi)有參照事件點(diǎn),每個(gè)倒計(jì)時(shí),誤差幾十毫秒,基本上是用戶(hù)無(wú)感知的。但是有一些情況下,例如視頻播放的倒計(jì)時(shí),這種有參照的情況下,幾分鐘的倒計(jì)時(shí),誤差幾秒鐘,就是非常明顯的 Bug 了。

這就是不穩(wěn),那么,如何把倒計(jì)時(shí)做的穩(wěn)呢?

2、 使用 CountDownTimer

實(shí)現(xiàn)一個(gè)倒計(jì)時(shí), Android 其實(shí)是提供了對(duì)應(yīng)的支持類(lèi)的,那就是 CounDownTimer ,它處于 android.os 包下的,完全可以實(shí)現(xiàn)一個(gè)倒計(jì)時(shí)的邏輯。

我們先看看它是如何使用的。

CountDownTimer 的使用非常的簡(jiǎn)單,在 onTick() 中監(jiān)聽(tīng)倒計(jì)時(shí)的變化,結(jié)束的時(shí)候會(huì)去調(diào)用 onFinish()。

繼續(xù)運(yùn)行一下看看 Log 的輸出情況。

這個(gè)總時(shí)長(zhǎng),誤差已經(jīng)是毫秒級(jí)的了,看樣子比我們自己實(shí)現(xiàn)的好很多。

再仔細(xì)看看,onTick() 方法回調(diào)的參數(shù),是一個(gè) 毫秒 為單位的數(shù)值,而這個(gè)數(shù)值,其實(shí)是有誤差的,但是這個(gè)其實(shí)也不影響,只需要對(duì)其進(jìn)行四舍五入的運(yùn)算,就可以得到正確的倒計(jì)時(shí)秒數(shù)。

例如:2830 就是 3s,1828 就是 2s。

但是再仔細(xì)看看,就能發(fā)現(xiàn)問(wèn)題,如果使用這種方式來(lái)處理倒計(jì)時(shí)的話,你會(huì)發(fā)現(xiàn),拿不到 1s 的狀態(tài),會(huì)直接 3s - 2s - finish,這個(gè)問(wèn)題,從 Log 上也可以反應(yīng)出來(lái)。

這就很尷尬了,有沒(méi)有參照物,都是一個(gè) Bug,只能先看看 CountDownTimer 的源碼了,它是如何保證總時(shí)長(zhǎng)的準(zhǔn)確的。

 

從 CountDownTimer 的結(jié)構(gòu)可以看出,它實(shí)際上也是使用 mHandler 來(lái)做的延遲,繼續(xù)看最重要的 Handler 的實(shí)現(xiàn)代碼。

 

在 handleMessage() 中,用到了一個(gè) SystemClock.elapsedRealtime() ,它實(shí)際上獲取到的是一個(gè) 系統(tǒng) 啟動(dòng)之后,到現(xiàn)在的一個(gè)絕對(duì)時(shí)間,包含系統(tǒng)休眠的間隔。

 

但是,它并不是關(guān)鍵,關(guān)鍵在于,CountDownTimer 會(huì)使用這個(gè)時(shí)間,每次計(jì)算出一個(gè)相對(duì) 1s 間隔的差值,也就是說(shuō),每次都去糾正這個(gè)誤差值,來(lái)保證最終的總時(shí)長(zhǎng)誤差是毫秒級(jí)(其實(shí)就是***一次 postDelayed() 的誤差)。

既然找到了 CountDownTimer 保證時(shí)間準(zhǔn)確行的關(guān)鍵點(diǎn),那么我們可以改寫(xiě)***個(gè) Demo 的代碼,來(lái)解決沒(méi)有 1s 狀態(tài)的問(wèn)題。

3、 動(dòng)態(tài)計(jì)算 delay 值

沒(méi)什么好說(shuō)的,就是計(jì)算此次間隔耗時(shí),然后比 1s 多出來(lái)的毫秒值,從下一個(gè) 1s 中減去,來(lái)糾正間隔時(shí)長(zhǎng)。

 

既然實(shí)現(xiàn)了之后,我們?cè)倏纯摧敵龅?Log。

 

可以看到,interval 每一次都在動(dòng)態(tài)的調(diào)整,每一秒的狀態(tài)都會(huì)更新出去,并且總時(shí)長(zhǎng)也保證誤差在毫秒級(jí)的,基本上***解決了倒計(jì)時(shí)的問(wèn)題了。

三、小結(jié)

一個(gè)倒計(jì)時(shí),簡(jiǎn)簡(jiǎn)單單使用 Handler.postDelayed() 也是無(wú)法保證準(zhǔn)和穩(wěn)的。細(xì)節(jié)決定成敗,一個(gè)倒計(jì)時(shí)也是可以做到***的。

【本文為51CTO專(zhuān)欄作者“張旸”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過(guò)微信公眾號(hào)聯(lián)系作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來(lái)源: 51CTO專(zhuān)欄
相關(guān)推薦

2022-10-21 15:42:21

倒計(jì)時(shí)鴻蒙

2014-08-18 14:30:27

Android倒計(jì)時(shí)

2014-03-21 13:46:45

2011-04-11 09:17:28

Ubuntu倒計(jì)時(shí)

2015-03-23 17:58:04

驗(yàn)證碼倒計(jì)時(shí)并行

2011-04-11 09:50:56

Ubuntu 11.0

2014-02-18 10:36:33

2022-06-14 08:45:27

瀏覽器IEWindows

2013-10-08 09:24:39

Windows 8.1Windows 8

2013-04-09 10:01:18

微軟Windows XP

2020-10-28 17:54:49

成都信息安全

2019-12-13 19:37:00

BashLinux命令

2013-10-10 09:23:15

Android 4.4Kitkat

2012-12-28 13:50:00

2015-01-21 16:07:57

Android源碼驗(yàn)證碼倒計(jì)時(shí)

2012-03-28 09:37:07

Ubuntu 12.0倒計(jì)時(shí)

2025-04-11 08:42:37

JavaScript倒計(jì)時(shí)前端

2013-06-06 11:27:52

iRadioWWDC2013

2017-02-09 16:35:17

戴爾
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)