在项目开发过程中,经常会遇到类似这样的需求:这个广告Banner需要3秒切换一次。这种重复的定时任务,我们有以下几种不同的实现方式,各有优劣。
1.用Handler实现
Handler handler;
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 0:
//时间到达之后需要做的处理--UI线程
mFlipper.showNext();
if(!isStop){
Message msg = handler.obtainMessage(0);
handler.sendMessageDelayed(msg, 3000);
}
break;
}
}
};
这些搞定之后,调用一条,即可开始执行
Message msg = handler.obtainMessage(0);
handler.sendMessageDelayed(msg, 1000);
通过发送一个Message来启动这个循环的定时任务,在每次执行完成任务之后,handler会发送一个3秒后处理的消息给自己,从而达到循环,实现功能。需要停止的话就加一个标志位开关,开始的时候再次调用上面的语句即可。
2.用Thread+Handler实现
这个实现方法实际上是把第一种方法的handler我发送消息的功能拆开来,交给自己定制的Thread来处理
Handler handler;
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 0:
//时间到达之后需要做的处理--UI线程
mFlipper.showNext();
break;
}
}
};
同上,实现一个处理任务的Handler,这里就不需要给handler自己发送延时消息了
class ShowNextRunnable implements Runnable {
public void run() {
while(true){
Message msg = handler.obtainMessage(0);
msg.sendToTarget();
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
实现一个Runnable来处理发送的逻辑判断。
new Thread(new ShowNextRunnable()).run();
使用这句来启动线程,开始循环执行定时任务。
使用Thread,就会遇到不能很方便的停止的问题,interrupt又得处理异常问题,自己加判断标志位的话,就需要兼容处理Thread.Sleep()这个时间的不响应问题,挺闹心的,又可以完善的好方法,希望可以分享下。
3.用Timer+TimerTask+Handler来实现
首先实现一个Handler来处理到达时间后需要执行的工作
Handler handler;
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what){
case 0:
//时间到达之后需要做的处理--UI线程
mFlipper.showNext();
break;
}
}
};
然后实现一个TimerTask来给handler发送执行工作的消息,由于涉及到主线程操作,所以不能在TimerTask里面直接执行
class ShowNextTask extends TimerTask{
public ShowNextTask(){
}
@Override
public void run() {
Message msg = handler.obtainMessage(0);
msg.sendToTarget();
}
}
最后实现一个Timer来执行时间的循环判断并在需要的时候调用我们的TimerTask
Timer timer;
timer = new Timer(true);
timer.schedule(new ShowNext(), 1000, 3000);
这样整个流程就搞定了,任务会在1秒后开始每次3秒的循环调用ShowNext()这个任务,从而实现了每隔多少时间执行一次重复任务的功能。
以上是我想到或者遇到用到的几种方法,至于各自的比较明确的优缺点还没有搞太明白,望高人补充