1.util包下的Timer實(shí)現(xiàn)倒計(jì)時(shí):

創(chuàng)新互聯(lián)客戶idc服務(wù)中心,提供成都服務(wù)器托管、成都服務(wù)器、成都主機(jī)托管、成都雙線服務(wù)器等業(yè)務(wù)的一站式服務(wù)。通過各地的服務(wù)中心,我們向成都用戶提供優(yōu)質(zhì)廉價(jià)的產(chǎn)品以及開放、透明、穩(wěn)定、高性價(jià)比的服務(wù),資深網(wǎng)絡(luò)工程師在機(jī)房提供7*24小時(shí)標(biāo)準(zhǔn)級(jí)技術(shù)保障。
2.使用Handler實(shí)現(xiàn)倒計(jì)時(shí)
3.使用Rxjava實(shí)現(xiàn)倒計(jì)時(shí)
在開發(fā)倒計(jì)時(shí)功能時(shí)往往我們會(huì)為了方便直接使用CountDownTimer或者使用Handler做延時(shí)來實(shí)現(xiàn),當(dāng)然CountDownTimer內(nèi)部封裝也是使用的Handler。
如果只是做次數(shù)很少的倒計(jì)時(shí)或者不需要精確的倒計(jì)時(shí)邏輯那倒沒關(guān)系,比如說我只要倒計(jì)時(shí)10秒,或者我大概5分鐘請(qǐng)求某個(gè)接口
但是如果是需要做精確的倒計(jì)時(shí)操作,比如說手機(jī)發(fā)送驗(yàn)證碼60秒,那使用現(xiàn)有的倒計(jì)時(shí)方案就會(huì)存在問題。可能有些朋友沒有注意到這一點(diǎn),下面我們就來簡(jiǎn)單分析一下現(xiàn)有倒計(jì)時(shí)的問題。
這個(gè)可能是用得最多的,因?yàn)榉奖懵铩5鋵?shí)倒計(jì)時(shí)每一輪倒計(jì)時(shí)完之后都是存在誤差的,如果看過CountDownTimer的源碼你就會(huì)知道,他的內(nèi)部是有做 校準(zhǔn)操作 的。(源碼很簡(jiǎn)單這里就不分析了)
但是如果你認(rèn)真的測(cè)試過CountDownTimer,你就會(huì)發(fā)現(xiàn),即便它內(nèi)部有做校準(zhǔn)操作,他的沒一輪都是有偏差,只是他最后一次倒計(jì)時(shí)完之后的總共時(shí)間和開始倒計(jì)時(shí)的時(shí)間相比沒偏差。
什么意思呢,意思就是1秒,2.050秒,3.1秒......,這樣的每輪偏差,導(dǎo)致他會(huì)出現(xiàn)10.95秒,下一次12秒的情況,那它的回調(diào)中如果你直接做取整就會(huì)出現(xiàn)少一秒的情況,但實(shí)際是沒少的。
這只是其中的一個(gè)問題,你可以不根據(jù)它的回調(diào)做展示,自己用一個(gè)整形累加做展示也能解決。但是他還有個(gè)問題,有概率直接出現(xiàn)跳秒,就是比如3秒,下次直接5秒,這是實(shí)際的跳秒,是少了一次回調(diào)的那種。
跳秒導(dǎo)致你如果直接使用它可能會(huì)大問題,你可能自測(cè)的時(shí)候沒發(fā)現(xiàn),到時(shí)一上線應(yīng)用在用戶那概率跳秒,那就蛋疼了。
不搞這么多花里胡哨的,直接使用Handler來實(shí)現(xiàn),會(huì)有什么問題。
因?yàn)橹苯邮褂胔andler來實(shí)現(xiàn),沒有校準(zhǔn)操作,每次循環(huán)會(huì)出現(xiàn)幾毫秒的誤差,雖然比CountDownTimer的十幾毫秒的誤差要好, 但是在基數(shù)大的倒計(jì)時(shí)情況下誤差會(huì)累計(jì),導(dǎo)致最終結(jié)果和現(xiàn)實(shí)時(shí)間差幾秒誤差,時(shí)間越久,誤差越大
直接使用Timer也一樣,只不過他每輪的誤差更小,幾輪才有1毫秒的誤差,但是沒有校準(zhǔn)還是會(huì)出現(xiàn)誤差累計(jì),時(shí)間越久誤差越大。
既然無法直接使用原生的,那我們就自己做一個(gè)。
我們基于Handler進(jìn)行封裝,從上面可以看出主要為了解決兩個(gè)問題,時(shí)間校準(zhǔn)和跳秒。自己寫一個(gè)CountDownTimer
思路就是在倒計(jì)時(shí)開始前獲取一次SystemClock.elapsedRealtime(),沒輪倒計(jì)時(shí)再獲取一次SystemClock.elapsedRealtime()相減得到誤差,根據(jù)delay校準(zhǔn)。然后使用while循壞來處理跳秒的操作,與原生的CountDownTimer不同,這里如果跳了多少秒,就會(huì)返回多少次回調(diào)。
安卓實(shí)現(xiàn)同時(shí)多個(gè)倒計(jì)時(shí)效果的步驟:
我們首先需要在輸入框中輸入一個(gè)秒數(shù),比如:12,然后獲取輸入框中的值,顯示在一個(gè)TextView中;
點(diǎn)擊“開始倒計(jì)時(shí)”按鈕,每隔一秒鐘,秒數(shù)減1,然后顯示在TextView中;
點(diǎn)擊“停止倒計(jì)時(shí)”按鈕,計(jì)時(shí)器停止運(yùn)行,當(dāng)再次點(diǎn)擊“開始倒計(jì)時(shí)”按鈕,計(jì)時(shí)器繼續(xù)運(yùn)行。
平時(shí)用的每個(gè)商品都應(yīng)該有兩個(gè)屬性值,這里叫它deadLine和isOverdue吧,表示商品的到期時(shí)間和是否到期,那么倒計(jì)時(shí)可以考慮這么實(shí)現(xiàn):設(shè)置一個(gè)主計(jì)時(shí)器,每隔1秒發(fā)出消息告訴GridView現(xiàn)在的時(shí)間,GridView的Item獲得這個(gè)時(shí)間之后就和deadLine比較,如果已經(jīng)到deadline了,就把數(shù)據(jù)源中的這項(xiàng)標(biāo)記成已到期(修改isOverdue的值為true);沒到deadline,就計(jì)算還差多少時(shí)間,顯示到GridView的Item里。
你好,
首先需要在輸入框中輸入一個(gè)秒數(shù),比如:12,然后獲取輸入框中的值,顯示在一個(gè)TextView中;點(diǎn)擊“開始倒計(jì)時(shí)”按鈕,每隔一秒鐘,秒數(shù)減1,然后顯示在TextView中;點(diǎn)擊“停止倒計(jì)時(shí)”按鈕,計(jì)時(shí)器停止運(yùn)行,當(dāng)再次點(diǎn)擊“開始倒計(jì)時(shí)”按鈕,計(jì)時(shí)器繼續(xù)運(yùn)行。
1、美圖倒數(shù)日
美圖倒數(shù)日,一款十分方便的倒計(jì)時(shí)實(shí)用軟件,在這里你可以將每個(gè)重要的日子都記錄下來,添加記錄后你也可以在桌面添加一個(gè)小工具,隨時(shí)都能夠在這里查看記錄日期。
2、天天計(jì)時(shí)
天天計(jì)時(shí)(Multi Timer:Time Helper)是一款精確度十分高的計(jì)時(shí)服務(wù)軟件,時(shí)間的記錄管理可以讓你養(yǎng)成更好的習(xí)慣,你可以使用這款軟件記錄每日的工作、節(jié)日、紀(jì)念日等等內(nèi)容,感興趣的朋友快來下載。
3、日期倒計(jì)時(shí)
日期倒計(jì)時(shí)是一款極簡(jiǎn)風(fēng)的日期記錄軟件,支持進(jìn)行多種內(nèi)容、格式記錄,同時(shí)提醒的鈴聲以及內(nèi)容都是可以進(jìn)行自由設(shè)置的,軟件也提供了多種主題供用戶進(jìn)行挑選。
4、小時(shí)光
生活是需要一定儀式感的,比如跨年的那一刻、你生日的那一刻,都可以用這款小時(shí)光app來進(jìn)行倒計(jì)時(shí)!操作起來沒有任何的難度,意義十足,喜歡的小伙伴快來試一試!
5、網(wǎng)紅生日倒計(jì)時(shí)
網(wǎng)紅生日倒計(jì)時(shí)制作器要不要來了解一下呢!想要完成這個(gè)東西其實(shí)只要下載視+AR就可以進(jìn)行制作了。
Android實(shí)現(xiàn)計(jì)時(shí)與倒計(jì)時(shí)的五種方法:
方法一
Handler與Message(不用TimerTask)
public class timerTask extends Activity{
private int recLen = 11;
private TextView txtView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.timertask);
txtView = (TextView)findViewById(R.id.txttime);
Message message = handler.obtainMessage(1); // Message
handler.sendMessageDelayed(message, 1000);
}
final Handler handler = new Handler(){
public void handleMessage(Message msg){ // handle message
switch (msg.what) {
case 1:
recLen--;
txtView.setText("" + recLen);
if(recLen 0){
Message message = handler.obtainMessage(1);
handler.sendMessageDelayed(message, 1000); // send message
}else{
txtView.setVisibility(View.GONE);
}
}
super.handleMessage(msg);
}
};
}
linux
方法二
Handler與Thread(不占用UI線程)
public class timerTask extends Activity{
private int recLen = 0;
private TextView txtView;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.timertask);
txtView = (TextView)findViewById(R.id.txttime);
new Thread(new MyThread()).start(); // start thread
}
final Handler handler = new Handler(){ // handle
public void handleMessage(Message msg){
switch (msg.what) {
case 1:
recLen++;
txtView.setText("" + recLen);
}
super.handleMessage(msg);
}
};
public class MyThread implements Runnable{ // thread
@Override
public void run(){
while(true){
try{
Thread.sleep(1000); // sleep 1000ms
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}catch (Exception e) {
}
}
}
}
}
方法三
Timer與TimerTask(Java實(shí)現(xiàn))
public class timerTask extends Activity{
private int recLen = 11;
private TextView txtView;
Timer timer = new Timer();
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.timertask);
txtView = (TextView)findViewById(R.id.txttime);
timer.schedule(task, 1000, 1000); // timeTask
}
TimerTask task = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() { // UI thread
@Override
public void run() {
recLen--;
txtView.setText(""+recLen);
if(recLen 0){
timer.cancel();
txtView.setVisibility(View.GONE);
}
}
});
}
};
}
方法四
TimerTask與Handler(不用Timer的改進(jìn)型)
public class timerTask extends Activity{
private int recLen = 11;
private TextView txtView;
Timer timer = new Timer();
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.timertask);
txtView = (TextView)findViewById(R.id.txttime);
timer.schedule(task, 1000, 1000); // timeTask
}
final Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
switch (msg.what) {
case 1:
txtView.setText(""+recLen);
if(recLen 0){
timer.cancel();
txtView.setVisibility(View.GONE);
}
}
}
};
TimerTask task = new TimerTask() {
@Override
public void run() {
recLen--;
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
}
方法五
Handler與Runnable(最簡(jiǎn)單型)
public class timerTask extends Activity{
private int recLen = 0;
private TextView txtView;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.timertask);
txtView = (TextView)findViewById(R.id.txttime);
handler.postDelayed(runnable, 1000);
}
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
recLen++;
txtView.setText("" + recLen);
handler.postDelayed(this, 1000);
}
};
}
計(jì)時(shí)與倒計(jì)時(shí)
方法1,方法2和方法3,都是倒計(jì)時(shí)
方法4,方法5,都是計(jì)時(shí)
計(jì)時(shí)和倒計(jì)時(shí),都可使用上述方法實(shí)現(xiàn)(代碼稍加改動(dòng))
UI線程比較
方法1,方法2和方法3,都是在UI線程實(shí)現(xiàn)的計(jì)時(shí);
方法4和方法5,是另開Runnable線程實(shí)現(xiàn)計(jì)時(shí)
實(shí)現(xiàn)方式比較
方法1,采用的是Java實(shí)現(xiàn),即Timer和TimerTask方式;
其它四種方法,都采用了Handler消息處理
推薦使用
如果對(duì)UI線程交互要求不很高,可以選擇方法2和方法3
如果考慮到UI線程阻塞,嚴(yán)重影響到用戶體驗(yàn),推薦使用方法4,另起線程單獨(dú)用于計(jì)時(shí)和其它的邏輯處理
方法5,綜合了前幾種方法的優(yōu)點(diǎn),是最簡(jiǎn)的
網(wǎng)站欄目:android倒計(jì)時(shí),Android倒計(jì)時(shí)代碼怎么寫
當(dāng)前URL:http://chinadenli.net/article25/dsihici.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、微信小程序、網(wǎng)站設(shè)計(jì)、、靜態(tài)網(wǎng)站、網(wǎng)站設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容