一直以来就想写技术博文了,之前有在csdn写过,最近一段时间csdn不知道什么问题,无法写博客。平时也喜欢看简书的博文。于是就想在简书上写些东西。这是我在简书的第一篇博客,有什么纰漏,望各位看官批评指正。
最近在写定时的一些功能,比如验证码,定时器什么的。想想就想把这一块功能实现给总结一下。分享给给位道友。本着开源精神,后期我会抽出工具类。不多说,下面是我的三种实现方式:
1.通过Timer与TimerTask实现
2.通过CountdownTimer进行实现
3.通过Handler与Message实现
4.通过Handler加Thread实现
5.通过Handler与Runnable实现
对于倒计时个人喜欢用第二种,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秒计数一次
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毫秒会回调一次*/
tv_time.setText("剩余"+ (l /1000) +"秒");
tv_time.setEnabled(false);
}
@Override
public voidonFinish() {
/*计时完成后回调*/
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);//第二个参数代表1秒后执行,设置为0就是马上执行,第三个参数代表每间隔1秒执行一次
}
});
}
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实现
第二种方式CountDownTimer非常适合倒计时的实现,是Android里面封装的倒计时类,使用简单,可在回调中直接做ui改变。
第三种方式就比较偏向安卓的写法了handler + message。后面两种采用子线程与ui线程分离。我推荐使用第二种或者第四种。谷歌官方使用的是CountdownTimer,很适合于倒计时的需求。