Reputation: 105
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_time
displays 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
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