解决方案
- 普通线程sleep的方式实现定时任务
- Timer实现定时任务
- ScheduledExecutorService实现定时任务
- Handler实现定时任务
- AlarmManager实现精确定时操作
1.普通线程sleep的方式实现定时任务
创建一个thread,然后让它在while循环里一直运行着,通过sleep方法来达到定时任务的效果,这是最常见的,可以快速简单地实现。但是这是Java中的实现方式,不建议使用
public class ThreadTask {
public static void main(String[] args) {
final long timeInterval = 1000;
Runnable runnable = new Runnable() {
public void run() {
while (true) {
System.out.println("execute task");
try {
Thread.sleep(timeInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
}
2. Timer实现定时任务
和普通线程+sleep(long)+Handler的方式比,优势在于
可以控制TimerTask的启动和取消
第一次执行任务时可以指定delay的时间。
在实现时,Timer类调度任务,TimerTask则是通过在run()方法里实现具体任务(然后通过Handler与线程协同工作,接收线程的消息来更新主UI线程的内容)。
Timer实例可以调度多任务,它是线程安全的。当Timer的构造器被调用时,它创建了一个线程,这个线程可以用来调度任务。
/**
* start Timer
*/
protected synchronized void startPlayerTimer() {
stopPlayerTimer();
if (playTimer == null) {
playTimer = new PlayerTimer();
Timer m_musictask = new Timer();
m_musictask.schedule(playTimer, 5000, 5000);
}
}
/**
* stop Timer
*/
protected synchronized void stopPlayerTimer() {
try {
if (playTimer != null) {
playTimer.cancel();
playTimer = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public class PlayerTimer extends TimerTask {
public PlayerTimer() {
}
public void run() {
//execute task
}
}
然而Timer是存在一些缺陷的
Timer在执行定时任务时只会创建一个线程,所以如果存在多个任务,且任务时间过长,超过了两个任务的间隔时间,会发生一些缺陷
如果Timer调度的某个TimerTask抛出异常,Timer会停止所有任务的运行
Timer执行周期任务时依赖系统时间,修改系统时间容易导致任务被挂起(如果当前时间小于执行时间)
注意:
Android中的Timer和java中的Timer还是有区别的,但是大体调用方式差不多
Android中需要根据页面的生命周期和显隐来控制Timer的启动和取消
ScheduledExecutorService实现定时任务
ScheduledExecutorService是从JDK1.5做为并发工具类被引进的,存在于java.util.concurrent,这是最理想的定时任务实现方式。
相比于上面两个方法,它有以下好处:
相比于Timer的单线程,它是通过线程池的方式来执行任务的,所以可以支持多个任务并发执行 ,而且弥补了上面所说的Timer的缺陷
可以很灵活的去设定第一次执行任务delay时间
提供了良好的约定,以便设定执行的时间间隔
简例: