最近做项目,定时更新图片,刚做完,总结一下。
使用PopupWindow,定时器结束,popup消失。
用到了2个定时器类:CountdownTimer 和 Timer 。
开始选择CountdownTimer,但是项目中有个功能,是点击跳过,停止当前图片的倒计时。
CountdownTimer类是同步的,调用cancel方法无效(后面讲原因)。
最后改为使用Timer。成功实现功能。
下面写个小例子:
private CountDownTimer timer = new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
tv_time.setText((millisUntilFinished / 1000) + "");
}
@Override
public void onFinish() {
popup.dismiss();
}
};
调用的时候很简单:timer.start();
CountDownTimer timer = new CountDownTimer(10000, 1000)中,构造方法中,
第一个参数表示总时间,
第二个参数表示间隔时间。
意思就是每隔一秒会回调一次方法onTick,然后10秒之后会回调onFinish方法。
问题:当点击跳过按钮,调用time.cancel();方法时,无效。在百度上查找,发现是CountDownTimer的问题。
在5.0及以上的系统中,cancel方法就可以起到作用。对比CountDownTimer的源码发现,在5.0中,增加了一个字段;
具体原因我就不赘述了,百度都能找到。于是果断放弃CountDownTimer。
下面使用Timer:
Timer timer = new Timer();
timer.schedule(new Task(), 1000, 1000); // timeTask
//活动弹窗定时任务
class Task extends TimerTask{
@Override
public void run() {
runOnUiThread(new Runnable() { // UI thread
@Override
public void run() {
Message message = new Message();
message.what = 1;
handler1.sendMessage(message);
}
});
}
}
//活动弹窗handler
Handler handler1 = new Handler(){
@Override
public void handleMessage(Message msg){
switch (msg.what) {
case 1:
if(huodongList.size()<=indexPopImage){
timer.cancel();
pop.dismiss();
}
if((indexCurrent != indexPopImage) &&(huodongList.size()>indexPopImage)){//换图片
String imageUrl = huodongList.get(indexPopImage).getPictureUrl();
ImageLoaderTools.displayImage(imageUrl, iv);
indexCurrent++;
}
tv_time.setText(""+second);
second =second-1;
if(second <= 0){
if(huodongList.size()==indexPopImage){
timer.cancel();
pop.dismiss();
}else{
indexPopImage++;
timer.cancel();
timer = new Timer();
second = totalSecond;
mytask =new Task();
timer.schedule(mytask, 1000, 1000);
}
}
}
}
};
点击跳过:
//点击跳过
bt_skip.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
indexPopImage++;
timer.cancel();
timer = new Timer();
second = totalSecond;
mytask =new Task();
timer.schedule(mytask, 1000, 1000);
}
});
注意:timer = new Timer(); 和 mytask =new Task();
1、所以同一个定时器任务只能被放置一次,当你要把这个任务重新执行一次的时候,要
mytask.cancel();
mytask =new Task();
重新给mytask赋值一个new Task(),否则会报异常:TimerTask is scheduled already。
2、timer.schedule方法:
schedule(TimerTask task, long delay)
schedule(TimerTask task, long delay, long period)
这两个方法:
task:要执行的任务
delay:延迟执行task的时间,用户调用 schedule() 方法后,要等待这么长的时间才可以第一次执行run() 方法。
period:每隔多长时间,重复执行task
3、Timer终止的问题:
默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。可以通过以下3种方法终止一个timer线程:
(1)调用timer的cancle方法。你可以从程序的任何地方调用此方法,甚至在一个timer task的run方法里;
(2)让timer线程成为一个daemon线程(可以在创建timer时使用new Timer(true)达到这个目地),这样当程序只有daemon线程的时候,它就会自动终止运行;
(3)调用System.exit方法,使整个程序(所有线程)终止。
使用Timer的cancel方法。这样会终止这个timer,终止timer下排定的TimerTask,允许现在正在执行的TimerTask继续执行,直到结束,然后终止timer的线程。
4、timer.cancel();和TimerTask.cancel();
timer.cancel():调用后,task任务如果正在执行,则会继续执行
TimerTask.cancel():停止执行当前task任务;
所有建议这么写:
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
if (mTimerTask != null) {
mTimerTask.cancel();
mTimerTask = null;
}
好,就到这里。