Chronometer和CountDownTimer计时器
github传送门
目录
- 效果图
- 前言
- Timer + TimerTask + Handler
- Timer + TimerTask
- Handler
- Thread + Handler
- Handler + Runnable
- 最后
效果图
看下效果图, 这是五种不同的方式演示计时器. 当然不看源码是看不出差别的.
前言
这次的文章不知道能不能帮助大家, 但是对我自己的帮助还是蛮大的, 才知道自己原来用的方法不是最优而且也不是最简. 然后我之前有一篇文章是用官方控件和类实现的, 有兴趣可以看一下Chronometer和CountDownTimer计时器.
Timer + TimerTask + Handler
在TimerTask实例的run方法中用Handler实例发送消息, 用Timer实例启动计时器, 从0ms开始, 间隔1000ms.
case R.id.cv_start1:
if (mTimer1 == null && mTask1 == null) {
mTimer1 = new Timer();
mTask1 = new TimerTask() {
@Override
public void run() {
Message message = mHandler.obtainMessage(1);
mHandler.sendMessage(message);
}
};
mTimer1.schedule(mTask1, 0, 1000);
}
break;
case R.id.cv_stop1:
if (mTimer1 != null) {
mTimer1.cancel();
mTimer1 = null;
}
if (mTask1 != null) {
mTask1.cancel();
mTask1 = null;
}
break;
复制代码
Timer + TimerTask
比起第一种, 这种更Java, 但是可以少一个Handler实例.
if (mTimer2 == null && mTask2 == null) {
mTimer2 = new Timer();
mTask2 = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mTvTime2.setText(getTime());
}
});
}
};
mTimer2.schedule(mTask2, 0, 1000);
}
复制代码
Handler
这种方法就直接告别Timer和TimerTask了, 通过Handler的发消息延迟sendMessageDelayed以及不同的消息内容(就是what值)解决问题.
case R.id.cv_start3: {
Message message = mHandler.obtainMessage(2);
mHandler.sendMessage(message);
}
break;
case R.id.cv_stop3: {
Message message = mHandler.obtainMessage(3);
mHandler.sendMessage(message);
}
复制代码
case 2: {
mTvTime3.setText(getTime());
this.removeMessages(2);
Message message = this.obtainMessage(2);
this.sendMessageDelayed(message, 1000);
}
break;
case 3:
this.removeMessages(2);
break;
复制代码
Thread + Handler
老朋友Thread + Handler, 原来经常这么写, 现在不了(手动滑稽).
/**
* 启动线程
*/
private void startThread() {
if (mThread == null) {
mThread = new MyThread();
mThread.start();
}
}
/**
* 停止线程
*/
private void stopThread() {
if (mThread != null) {
mThread.stop = true;
mThread = null;
Message message = mHandler.obtainMessage(5);
mHandler.sendMessage(message);
}
}
复制代码
Handler + Runnable
最后一种我目前最喜欢. 你连what值都无需处理, 直接postDelayed设置时延, 然后交给实现Runnable接口的实例的run方法来做.
case R.id.cv_start5: {
if (mRunnable == null) {
mRunnable = new MyRunnable();
mHandler.postDelayed(mRunnable, 0);
}
}
break;
case R.id.cv_stop5: {
mHandler.removeCallbacks(mRunnable);
mRunnable = null;
}
break;
复制代码
private class MyRunnable implements Runnable {
@Override
public void run() {
mTvTime5.setText(getTime());
mHandler.postDelayed(this, 1000);
}
}
复制代码
最后
总之一点, 用第三种Handler和第五种Handler + Runnable肯定比其它的消耗少得多, 所以很推荐. 或者你还有更棒的方法可以评论区告诉我下. 喜欢记得点赞, 暗中关注我也是可以的哦~