0

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...

Mark023
  • 105
  • 12

1 Answers1

1

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();
        }
    };
}
Community
  • 1
  • 1
bradkratky
  • 1,577
  • 1
  • 14
  • 28
  • Ok I just have 1 timer and it is scheduled timer which I put in the function startUpCounting() as shown above. Currently what I did was, when dismiss() was called, the next line I give timer.cancel() but still does not work – Mark023 Jul 14 '16 at 14:25
  • Is the method being called? Can you include more code? Set it to null as well. – bradkratky Jul 14 '16 at 14:25
  • This method is being called only once in onFinish() of countdown timer and I set timer to null as well. Still not working..See my updated question – Mark023 Jul 14 '16 at 14:30
  • The code you posted shows it in a click method - that means it wouldn't be cancelled if the dialog is dismissed without clicking the button (such as clicking outside the dialog area) – bradkratky Jul 14 '16 at 14:36
  • No..handleClickAction() is called when the button is pressed. The handleClickAction() is inside onClick() – Mark023 Jul 14 '16 at 14:40
  • I updated my solution - but I just realized I'm using a `DialogFragment`, not a `Dialog`. I'll edit it again – bradkratky Jul 14 '16 at 14:54
  • Thank you :) I think this will work... Will it solve both the problems which I have mentioned in my question? – Mark023 Jul 14 '16 at 15:00
  • Yes the code I posted for `DialogFragment` solves both! – bradkratky Jul 14 '16 at 15:06
  • Ok it solved my first problem... But still sometimes there is 2nd problem. Is it because I am using 2 handlers? – Mark023 Jul 14 '16 at 15:07
  • The second problem is occurring because you have two instances running at the same time. I will edit my post for the full `Dialog` class. Be sure to add in your UI methods - I commented them out when I ran it, only using log. – bradkratky Jul 14 '16 at 15:09
  • Ok thank you... So I think I dont need onTimeHandler. Removing that would solve my problem? – Mark023 Jul 14 '16 at 15:12
  • You don't but I don't think it will. The most important part is the `onStop` method. Make sure it's exactly the same. And make sure you are setting the timer variable exactly the same. – bradkratky Jul 14 '16 at 15:13
  • Ok can you see my EDIT2. Also my scheduletimer code in the question – Mark023 Jul 14 '16 at 15:41