对话框关闭后如何停止预定的计时器

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();
        }
    };
}