曾经倒计时使用Timer和TimerTask来处理
private Timer timer = new Timer();
private long time;
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
time = time - 1000;
//TODO something
//通过handler发送消息更改界面
}
};
//普通的使用方式
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mTimeTv.setText("");
}
}
};
但是多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行。
替换方法:使用ScheduledExecutorService
private long time;
private ScheduledExecutorService timeService = new ScheduledThreadPoolExecutor(1, new ThreadPoolExecutor.AbortPolicy());
timeService.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
time = time - 1000;
handler.sendEmptyMessage(0);
}
}, initialDelay, period, TimeUnit unit);
initialDelay:the time to delay first execution
period :the period between successive executions
TimeUnit unit :the time unit of the initialDelay and period parameters
TimeUnit.DAYS //天
TimeUnit.HOURS //小时
TimeUnit.MINUTES //分钟
TimeUnit.SECONDS //秒
TimeUnit.MILLISECONDS //毫秒
//Handler正确使用方式,防止内存泄漏
static class MyHandler extends Handler {
private WeakReference<OrderDetailsActivity> mWeakReference;
private ScheduledExecutorService timeService;
private MyHandler(WeakReference<OrderDetailsActivity> mWeakReference) {
this.mWeakReference = mWeakReference;
timeService = mWeakReference.get().timeService;
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mWeakReference.get().updateText();
}
}
注:不能在handler里面直接调用mWeakReference.get().mTimeTv.setText("");
会抛异常:android.view.ViewRoot$CalledFromWrongThreadException
在activity里提出方法
/**
* handler调用更新界面
*/
private void updateText() {
mTimeTv.setText(getString(R.string.order_time02_task, d, h, m, s));
}
然后在不需要计时器的时候调用
@Override
protected void onDestroy() {
super.onDestroy();
//释放资源
if (timeService != null && !timeService.isShutdown()) {
timeService.shutdown();
}
}