之前项目中有一个需求,需要使用定时器在service启动后每1秒种自动获取一次location。第一时间想到了Timer,在java 或者Android中我们会经常用到Timer来做定时器,用来运行定时任务。Timer的用法很简单,只要定义好间隔时间和任务函数,Timer实例就会按指定间隔时间重复地执行任务函数。
经过一段时间的codeing,在验证时发现了一个问题:
修改系统当前时间为未来的时间时,定时器不会出现问题,会正常运行;而把当前时间修改为过去的时间,定时器会挂起。
通过分析Timer定时器源码得知,时间调整到当前时间之前,调定时器一定不会执行。
那么如何解决呢?
将Timer、TimerTask 替换为ScheduledExecutorService和ScheduledFuture运行定时任务,可以完美解决该问题,话不多说,直接上码:
public class TimerImpl implements TimerInterface {
private ScheduledExecutorService mScheduledExecutorService;
private ScheduledFuture<?> mScheduledFuture;
public TimerImpl() {
}
@Override
public void startTimer() {
if (mScheduledExecutorService == null) {
mScheduledExecutorService = Executors.newScheduledThreadPool(MagicNumberConstant.TWO);
mScheduledFuture = mScheduledExecutorService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
//执行任务
getLocation();
}
}, 0, 1000, TimeUnit.MILLISECONDS);
}
}
@Override
public void stopTimer() {
LogUtil.i("TimerImpl stopTimer ");
if (mScheduledFuture != null) {
mScheduledFuture.cancel(true);
mScheduledFuture = null;
}
mScheduledExecutorService = null;
}
/**
* getLocation
*/
private void getLocation() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
}
使用说明:
在需要的地方执行startTimer()方法开启定时任务,在需要停止的时候执行stopTimer()方法。
本文仅展现了实现类的部分代码,TimerInterface接口类需要自行完成实现。
好了,关于Timer定时器因修改系统时间导致挂起的解决方案就介绍到这里,谢谢。