对话框关闭后如何停止预定的计时器
how to stop scheduled timer after dialog is closed
我有一个定时计时器运行显示延迟上学。每当学生到达学校时,都会打开一个自定义对话框,其中显示 delay in arrival : 20.0 min
。它每半分钟递增 0.5min
。我的代码是 -
public void startTimer(long delay_minutes) {
final long delay = delay_minutes;
delay_countup = (double) delay;
//Start the scheduled time
departuretimer = new Timer();
departuretimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
countup = 0.0 + delay_countup;
Log.d("hi","Values 0" + delay_countup + countup);
mHandler.obtainMessage(1).sendToTarget();
delay_countup = delay_countup + 0.5;
Log.d("hi","Values 1" + delay_countup);
}
}, 0, 30000);
}
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
delay_time.setText(String.valueOf(countup) + "min");
rootView.invalidate();
}
};
问题是-
a) 即使为新来的学生打开对话框,计时器也会在后台为旧来的学生运行。我的意思是当对话框关闭时计时器永远不会被杀死。(对话框关闭只是为了确认学生的到来)
b) 有时文本视图 delay_time
显示错误的值。它显示 22.0min
,然后立即显示 0.5min
,然后再次显示 23.0min
。
这是为什么?
编辑 1:
单击对话框中的按钮后处理 timer cancel
private void handleClickAction() {
dismiss();
timer.cancel();
timer = null;
}
编辑 2:
日志始终显示正确的值,但在 UI 中有时会出现问题。问题是,例如 -
delay_countup = 50.0
countup = 50.0
Textview updates as 50.0 //This is correct
Now,
delay_countup = 50.5
countup = 50.5
Textview updates as 0.5 //This is incorrect. I need 50.5
有时会发生这种情况...
看来你从来没有删除第一个计时器。因此,当您初始化第二个计时器时,您有两个计时器同时尝试更新 UI.
将计时器存储为成员变量并在启动第二个之前检查它是否已初始化。当对话框关闭时,您应该 cancel()
Timer
。所以你还应该看看如何实现方法 when the dialog is dismissed - 这应该调用一个清理方法 cancel()
并将计时器设置为空。
public class DialogTest extends Dialog {
Timer timer;
double countup = 0;
double initial_time = 0;
public DialogTest(Context context){
super(context);
}
@Override
protected void onStart() {
super.onStart();
startUpCounting();
}
@Override
protected void onStop() {
Log.e("b", "timer stopped");
if(timer != null){
timer.cancel();
timer = null;
}
super.onStop();
}
public void startUpCounting() {
delay_for_student.setText("Delay in Arrival");
rootView.invalidate();
Log.e("b", "timer started");
if(timer != null){
timer.cancel();
timer = null;
}
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
countup = 0.0 + initial_time;
if (countup == 0.0) {
onTimeHandler.obtainMessage(1).sendToTarget();
} else {
mHandler.obtainMessage(1).sendToTarget();
}
initial_time = initial_time + 0.5;
}
}, 0, 1000);
}
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
Log.e("b", "timer: " + countup);
delay_time.setText(String.valueOf(countup) + "min");
rootView.invalidate();
}
};
public Handler onTimeHandler = new Handler() {
public void handleMessage(Message msg) {
Log.e("b", "timer ---");
delay_time.setText("-");
rootView.invalidate();
}
};
}
我有一个定时计时器运行显示延迟上学。每当学生到达学校时,都会打开一个自定义对话框,其中显示 delay in arrival : 20.0 min
。它每半分钟递增 0.5min
。我的代码是 -
public void startTimer(long delay_minutes) {
final long delay = delay_minutes;
delay_countup = (double) delay;
//Start the scheduled time
departuretimer = new Timer();
departuretimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
countup = 0.0 + delay_countup;
Log.d("hi","Values 0" + delay_countup + countup);
mHandler.obtainMessage(1).sendToTarget();
delay_countup = delay_countup + 0.5;
Log.d("hi","Values 1" + delay_countup);
}
}, 0, 30000);
}
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
delay_time.setText(String.valueOf(countup) + "min");
rootView.invalidate();
}
};
问题是-
a) 即使为新来的学生打开对话框,计时器也会在后台为旧来的学生运行。我的意思是当对话框关闭时计时器永远不会被杀死。(对话框关闭只是为了确认学生的到来)
b) 有时文本视图 delay_time
显示错误的值。它显示 22.0min
,然后立即显示 0.5min
,然后再次显示 23.0min
。
这是为什么?
编辑 1:
单击对话框中的按钮后处理 timer cancel
private void handleClickAction() {
dismiss();
timer.cancel();
timer = null;
}
编辑 2: 日志始终显示正确的值,但在 UI 中有时会出现问题。问题是,例如 -
delay_countup = 50.0
countup = 50.0
Textview updates as 50.0 //This is correct
Now,
delay_countup = 50.5
countup = 50.5
Textview updates as 0.5 //This is incorrect. I need 50.5
有时会发生这种情况...
看来你从来没有删除第一个计时器。因此,当您初始化第二个计时器时,您有两个计时器同时尝试更新 UI.
将计时器存储为成员变量并在启动第二个之前检查它是否已初始化。当对话框关闭时,您应该 cancel()
Timer
。所以你还应该看看如何实现方法 when the dialog is dismissed - 这应该调用一个清理方法 cancel()
并将计时器设置为空。
public class DialogTest extends Dialog {
Timer timer;
double countup = 0;
double initial_time = 0;
public DialogTest(Context context){
super(context);
}
@Override
protected void onStart() {
super.onStart();
startUpCounting();
}
@Override
protected void onStop() {
Log.e("b", "timer stopped");
if(timer != null){
timer.cancel();
timer = null;
}
super.onStop();
}
public void startUpCounting() {
delay_for_student.setText("Delay in Arrival");
rootView.invalidate();
Log.e("b", "timer started");
if(timer != null){
timer.cancel();
timer = null;
}
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
countup = 0.0 + initial_time;
if (countup == 0.0) {
onTimeHandler.obtainMessage(1).sendToTarget();
} else {
mHandler.obtainMessage(1).sendToTarget();
}
initial_time = initial_time + 0.5;
}
}, 0, 1000);
}
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
Log.e("b", "timer: " + countup);
delay_time.setText(String.valueOf(countup) + "min");
rootView.invalidate();
}
};
public Handler onTimeHandler = new Handler() {
public void handleMessage(Message msg) {
Log.e("b", "timer ---");
delay_time.setText("-");
rootView.invalidate();
}
};
}