? ? ? 一直以來就想寫技術(shù)博文了毁习,之前有在csdn寫過嗅虏,最近一段時間csdn不知道什么問題,無法寫博客汹胃。平時也喜歡看簡書的博文婶芭。于是就想在簡書上寫些東西。這是我在簡書的第一篇博客着饥,有什么紕漏犀农,望各位看官批評指正。
? ? ? 最近在寫定時的一些功能宰掉,比如驗證碼呵哨,定時器什么的赁濒。想想就想把這一塊功能實(shí)現(xiàn)給總結(jié)一下。分享給給位道友孟害。本著開源精神拒炎,后期我會抽出工具類。不多說挨务,下面是我的三種實(shí)現(xiàn)方式:
1.通過Timer與TimerTask實(shí)現(xiàn)
2.通過CountdownTimer進(jìn)行實(shí)現(xiàn)
3.通過Handler與Message實(shí)現(xiàn)
4.通過Handler加Thread實(shí)現(xiàn)
5.通過Handler與Runnable實(shí)現(xiàn)
對于倒計時個人喜歡用第二種击你,CountdownTimer是安卓封裝好的一個類,簡單易用且線程安全谎柄。對于計時可用4,5較為方便丁侄。不多說了直接上代碼
packagecom.jugui.timedemo;
importandroid.os.Bundle;
importandroid.os.CountDownTimer;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.support.v7.app.AppCompatActivity;
importandroid.view.View;
importandroid.widget.Button;
importandroid.widget.TextView;
importjava.util.Timer;
importjava.util.TimerTask;
public classMainActivityextendsAppCompatActivityimplementsView.OnClickListener {
privateTextViewtv_time;
privateButtonbtn_three;
privateButtonbtn_two;
privateButtonbtn_one;
privateButtonbtn_four;
privateButtonbtn_five;
private inttime;
privateTimertimer;
privateHandlermHandler=newHandler() {
@Override
public voidhandleMessage(Message msg) {
super.handleMessage(msg);
switch(msg.what) {
case1:
timer.cancel();
tv_time.setText("獲取驗證碼");
tv_time.setEnabled(true);
break;
case2:
case5:
tv_time.setText("剩余"+time+"秒");
tv_time.setEnabled(false);
break;
case3:
--time;
Message message =mHandler.obtainMessage(3);
if(time<=0) {
timer.cancel();
tv_time.setText("獲取驗證碼");
tv_time.setEnabled(true);
}else{
tv_time.setText("剩余"+time+"秒");
tv_time.setEnabled(false);
mHandler.sendMessageDelayed(message,1000);
}
case4:
tv_time.setText("獲取驗證碼");
tv_time.setEnabled(true);
break;
}
}
};
privateMyCountDownTimerdownTimer;
privateThreadthread;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private voidinitView() {
btn_one= (Button) findViewById(R.id.btn_one);
btn_two= (Button) findViewById(R.id.btn_two);
btn_three= (Button) findViewById(R.id.btn_three);
btn_four= (Button) findViewById(R.id.btn_four);
btn_five= (Button) findViewById(R.id.btn_five);
tv_time= (TextView) findViewById(R.id.tv_time);
btn_one.setOnClickListener(this);
btn_two.setOnClickListener(this);
btn_three.setOnClickListener(this);
btn_four.setOnClickListener(this);
btn_five.setOnClickListener(this);
}
@Override
public voidonClick(View view) {
switch(view.getId()) {
caseR.id.btn_one:
timeByTimer();
break;
caseR.id.btn_two:
timeByCount();
break;
caseR.id.btn_three:
timeByHandler();
break;
caseR.id.btn_four:
timeByThread();
break;
caseR.id.btn_five:
timeByRunnable();
break;
}
}
/**********************? ? ? ? ? ? ? ? Runnable? ? ? ? ? ? *********************************/
private voidtimeByRunnable() {
tv_time.setText("第五種獲取驗證碼");
time=60;
tv_time.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View view) {
mHandler.postDelayed(runnable,1000);
}
});
}
Runnablerunnable=newRunnable() {
@Override
public voidrun() {
--time;
if(time<=0) {
tv_time.setText("獲取驗證碼");
tv_time.setEnabled(true);
}else{
tv_time.setText("剩余"+time+"秒");
tv_time.setEnabled(false);
mHandler.postDelayed(this,1000);
}
}
};
/**********************? ? ? ? ? ? ? ? Runnable? ? ? ? ? ? *********************************/
/**********************? ? ? ? ? ? ? ? Thread? ? ? ? ? ? *********************************/
private voidtimeByThread() {
tv_time.setText("第四種獲取驗證碼");
time=60;
tv_time.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View view) {
thread=newThread(newMyThread());
thread.start();
}
});
}
classMyThreadimplementsRunnable {
@Override
public voidrun() {
while(true) {
try{
Thread.sleep(1000);
--time;
Message message =mHandler.obtainMessage();
if(time<=0) {
message.what=4;
}else{
message.what=5;
}
mHandler.sendMessage(message);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**********************? ? ? ? ? ? ? Thread? ? ? ? ? ? *********************************/
private voidtimeByHandler() {
tv_time.setText("第三種獲取驗證碼");
time=60;
tv_time.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View view) {
Message message =mHandler.obtainMessage(3);
mHandler.sendMessageDelayed(message,1000);
}
});
}
/**********************? ? ? ? ? ? ? ? CountDownTimer? ? ? ? ? ? *********************************/
private voidtimeByCount() {
//計時60秒,每隔1秒計數(shù)一次
tv_time.setText("第二種獲取驗證碼");
downTimer=newMyCountDownTimer(60000,1000);
tv_time.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View view) {
downTimer.start();
}
});
}
classMyCountDownTimerextendsCountDownTimer {
publicMyCountDownTimer(longmillisInFuture,longcountDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public voidonTick(longl) {
/*每隔countDownInterval毫秒會回調(diào)一次*/
tv_time.setText("剩余"+ (l /1000) +"秒");
tv_time.setEnabled(false);
}
@Override
public voidonFinish() {
/*計時完成后回調(diào)*/
tv_time.setText("獲取驗證碼");
tv_time.setEnabled(true);
}
}
/**********************? ? ? ? ? ? ? ? CountDownTimer? ? ? ? ? ? *********************************/
/**********************? ? ? ? ? ? ? ? TimerTask? ? ? ? ? ? *********************************/
private voidtimeByTimer() {
timer=newTimer();
time=60;
tv_time.setText("第一種獲取驗證碼");
tv_time.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View view) {
timer.schedule(newMyTimerTask(),1000,1000);//第二個參數(shù)代表1秒后執(zhí)行朝巫,設(shè)置為0就是馬上執(zhí)行鸿摇,第三個參數(shù)代表每間隔1秒執(zhí)行一次
}
});
}
classMyTimerTaskextendsTimerTask {
@Override
public voidrun() {
--time;
Message message =mHandler.obtainMessage();/*為什么不用new Message可以參考http://blog.csdn.net/h3c4lenovo/article/details/7914902*/
if(time<=0) {
message.what=1;
}else{
message.what=2;
}
mHandler.sendMessage(message);
}
}
/**********************? ? ? ? ? ? ? ? TimerTask? ? ? ? ? ? *********************************/
@Override
protected voidonDestroy() {
super.onDestroy();
if(timer!=null) {
timer.cancel();
timer=null;
}
if(downTimer!=null) {
downTimer.cancel();
downTimer=null;
}
if(thread!=null) {
thread=null;
}
}
}
第一種方式是采用java的Timer實(shí)現(xiàn)
第二種方式CountDownTimer非常適合倒計時的實(shí)現(xiàn),是Android里面封裝的倒計時類劈猿,使用簡單拙吉,可在回調(diào)中直接做ui改變。
第三種方式就比較偏向安卓的寫法了handler + message揪荣。后面兩種采用子線程與ui線程分離筷黔。我推薦使用第二種或者第四種。谷歌官方使用的是CountdownTimer变逃,很適合于倒計時的需求必逆。