Mark023
Mark023

Reputation: 105

how to stop scheduled timer after dialog is closed

I have a scheduled timer running to show the delay in coming to school. Whenever a student arrives to the school, a custom dialog opens up with display showing the delay in arrival : 20.0 min. It gets incremented by 0.5min every half a minute. My code is -

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

The problems are -

a) the timer runs in background for the old arrived student even when the dialog is opened for new arrived student. I mean the timer is never killed when the dialog is closed.(The dialog is closed only to confirm the arrival of the student)

b) Sometimes the textview delay_timedisplays wrong value. It shows 22.0min and immediately 0.5min and then again 23.0min.

Why is this?

EDIT 1: Handling timer cancel after click of button in the dialog

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

EDIT 2 : The logs always display correct values but in the UI sometimes there is a problem. The problem is that for example -

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

This happens sometimes...

Upvotes: 0

Views: 323

Answers (1)

bradkratky
bradkratky

Reputation: 1617

It seems that you are never removing the first timer. So when you initialize the second timer you have two timers simultaneously trying to update the UI.

Store the timer as a member variable and check if it's initialized before starting a second one. When the dialog is closed you should cancel() the Timer. So you should also see how to implement methods when the dialog is dismissed - this should call a cleanup method which cancel() and sets the timer to null.

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

Upvotes: 1

Related Questions