您的位置:首页 > 移动开发 > Android开发

Timer延时任务的坑与handler实现延时任务对比

2017-03-25 16:41 781 查看

Timer定时任务的坑与handler实现延时任务对比

1.Timer实现定时任务

下面是一个循环定时任务,在一般情况下并不会出什么差错。

Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
//do something you want
}
}, 3000, 3000);


然而当你修改了系统时间,问题就出现了,Timer任务很可能就不正常工作了,具体修改成什么时间会出现问题在此不研究。

为什么修改了时间会出问题?

带着这个问题我们看一些schedule方法的具体实现

public void schedule(TimerTask task, long delay, long period) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
if (period <= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, System.currentTimeMillis()+delay, -period);
}


看到最后一行,你就应该知道发生了什么状况

sched(task, System.currentTimeMillis()+delay, -period);


这里使用的是系统当前时间毫秒数+延时时间,到这里我们就不必再往下看了,延时任务使用了绝对时间作为标准,也就是说,当系统时间改变,肯定会影响这个任务的执行。至于如何影响,什么情况下会影响,再次不作深究。

2.handler实现定时任务

//定义msg.what常量
private static final int TIMER_TASK = 101;

//使用handler发送延时消息
mHandler.sendMessageDelayed(mHandler.obtainMessage(TIMER_TASK), 3000);

//在handler的处理方法中处理消息任务
public boolean handleMessage(Message msg) {
switch (msg.what) {
case TIMER_TASK:
//do something you want
mHandler.sendMessageDelayed(mHandler.obtainMessage(TIMER_TASK), 3000);
break;
default:
break;
}
return true;
}


可以看出来,这个跟Timer类似的循环任务,只不过是采用handler来实现,那么他们有什么区别吗?

Timer与Handler延时任务的区别

我们先来看一下mHandler.sendMessageDelayed是怎么实现的:

public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}


这里调用了

sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis,)


时间参数使用的是SystemClock.uptimeMillis() + delayMillis,也就是系统启动到当前的毫秒数+延时毫秒数。这时候我们就能知道,修改系统时间并不会改变这个数值,也就是说修改系统时间不影响handler的延时任务。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息