как остановить таймер по расписанию после закрытия диалога

У меня есть запланированный таймер, чтобы показать задержку прихода в школу. Всякий раз, когда учащийся приходит в школу, открывается специальное диалоговое окно с отображением 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();
        }
    };

Проблемы -

а) таймер работает в фоновом режиме для старого прибывшего студента, даже если диалог открыт для нового прибывшего студента. Я имею в виду, что таймер никогда не убивается при закрытии диалога. (Диалог закрывается только для подтверждения прихода ученика)

б) Иногда текстовое представление delay_timeотображает неправильное значение. Показывает 22.0min и сразу 0.5min и потом снова 23.0min.

Почему это?

EDIT 1: обработка timer cancel после нажатия кнопки в диалоговом окне

private void handleClickAction() {
        dismiss();
        timer.cancel();
        timer = null;
}

EDIT 2: журналы всегда отображают правильные значения, но в пользовательском интерфейсе иногда возникают проблемы. Проблема в том, что например -

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

Это бывает иногда...


person Mark023    schedule 14.07.2016    source источник


Ответы (1)


Кажется, что вы никогда не удаляете первый таймер. Поэтому, когда вы инициализируете второй таймер, у вас есть два таймера, одновременно пытающихся обновить пользовательский интерфейс.

Сохраните таймер как переменную-член и проверьте, инициализирован ли он перед запуском второго. Когда диалоговое окно закрыто, вы должны cancel() Timer. Таким образом, вы также должны увидеть, как реализовать методы при закрытии диалогового окна - это должно вызывать метод очистки, который 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();
        }
    };
}
person bradkratky    schedule 14.07.2016
comment
Хорошо, у меня есть только 1 таймер, и это запланированный таймер, который я поместил в функцию startUpCounting(), как показано выше. В настоящее время то, что я сделал, было то, что когда был вызван метод отклонения (), следующая строка, которую я даю timer.cancel (), но все еще не работает - person Mark023; 14.07.2016
comment
Метод вызывается? Можете ли вы включить больше кода? Установите его на ноль, а также. - person bradkratky; 14.07.2016
comment
Этот метод вызывается только один раз в onFinish() таймера обратного отсчета, и я также установил для таймера значение null. Все еще не работает .. Смотрите мой обновленный вопрос - person Mark023; 14.07.2016
comment
Размещенный вами код показывает его в методе щелчка - это означает, что он не будет отменен, если диалоговое окно будет закрыто без нажатия кнопки (например, нажатие за пределами области диалога) - person bradkratky; 14.07.2016
comment
No..handleClickAction() вызывается при нажатии кнопки. handleClickAction() находится внутри onClick() - person Mark023; 14.07.2016
comment
Я обновил свое решение, но только что понял, что использую DialogFragment, а не Dialog. Я снова отредактирую - person bradkratky; 14.07.2016
comment
Спасибо :) Думаю, это сработает... Решит ли это обе проблемы, о которых я упомянул в своем вопросе? - person Mark023; 14.07.2016
comment
Да, код, который я разместил для DialogFragment, решает оба! - person bradkratky; 14.07.2016
comment
Хорошо, это решило мою первую проблему ... Но все же иногда возникает вторая проблема. Это потому, что я использую 2 обработчика? - person Mark023; 14.07.2016
comment
Вторая проблема возникает из-за того, что у вас одновременно запущено два экземпляра. Я отредактирую свой пост для полного Dialog класса. Обязательно добавьте в свои методы пользовательского интерфейса — я закомментировал их при запуске, используя только log. - person bradkratky; 14.07.2016
comment
Хорошо, спасибо ... Так что я думаю, что мне не нужен onTimeHandler. Удаление этого решит мою проблему? - person Mark023; 14.07.2016
comment
Вы нет, но я не думаю, что это будет. Наиболее важной частью является метод onStop. Убедитесь, что он точно такой же. И убедитесь, что вы устанавливаете переменную таймера точно так же. - person bradkratky; 14.07.2016
comment
Хорошо, вы можете увидеть мой EDIT2. Также мой код расписания в вопросе - person Mark023; 14.07.2016