So I click a start button and every second I change the text of a label with counting the time:
new CountDownTimer(30000, 500) {
public void onTick(long millisUntilFinished) {
if (zaciatokgotten) {
T2 = new Timer();
tt2 = new TimerTask() {
public void run() {
if(stopclicked == true) {
this.cancel();
}
handler.post(new Runnable() {
public void run() {
hasStartedtt2 = true;
calendar = Calendar.getInstance();
simpledate = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
do_casu = simpledate.format(calendar.getTime());
zaciatok_hour = zaciatok.substring(11, 13);
zaciatok_minute = zaciatok.substring(14, 16);
koniec_hour = do_casu.substring(11, 13);
koniec_minute = do_casu.substring(14, 16);
zaciatok_sekundy = zaciatok.substring(17, 19);
koniec_sekundy = do_casu.substring(17, 19);
final_hour = ((Integer.parseInt(koniec_hour) - Integer.parseInt(zaciatok_hour)) );
final_minute = Integer.parseInt(koniec_minute) - Integer.parseInt(zaciatok_minute);
final_seconds = Integer.parseInt(koniec_sekundy) - Integer.parseInt(zaciatok_sekundy) - 1;
if (final_seconds < 0) {
final_seconds = final_seconds + 60;
final_minute = final_minute - 1;
}
if (final_minute < 0) {
final_hour = final_hour - 1;
final_minute = final_minute + 60;
}
if (final_hour < 0) {
final_hour = 0;
}
if (final_minute < 0) {
final_minute = 0;
}
if (final_hour == 0) {
if (final_minute == 0) {
txtProgress.setText(final_seconds + " s");
} else {
txtProgress.setText(final_minute + " m " + final_seconds + " s");
}
} else {
txtProgress.setText(final_hour + " h " + final_minute + " m " + final_seconds + " s");
}
}
});
}
};
T2.schedule(tt2, 1000, 1000);
if(once ==0) {
new Thread(new Runnable() {
@Override
public void run() {
while (pStatus <= 100) {
handler.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(pStatus);
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
pStatus++;
if (pStatus == 100) {
pStatus = 0;
}
}
}
}).start();
once++;
this.cancel();
}
}}
public void onFinish() {
}
}.start();
After I click the stop button the progressBar
stops spinning, which is correct, but the time keeps incrementing, what am I doing wrong? Note that this issue is not present on the phones I used to test it, but its present on tablet devices, maybe they handle threads differently?
The code for stopping the timer here:
stopclicked = true
if(hasStartedtt2 == true) {
tt2.cancel();
// handler.removeCallbacksAndMessages(null);
}
if (T2 != null) {
T2.cancel();
T2.purge();
}
pStatus = 101;
EDIT1: I just noticed it is stopped, but only 20 - 25 seconds after I clicked Stop, whats causing the delay?
The reason time won't stop (or stops "only 20 - 25 seconds after you clicked Stop") is the new instances of T2 = new Timer()
and tt2 = new TimerTask()
you create on every CountDownTimer
's onTick()
. The old instances of Timer
and TimerTask
keep residing on Java heap making their job until getting garbage-collected. You may notice the time changes being bumpy.
Moreover, you seem to overcomplicate the task implementation. You might not need neither Timer
nor TimerTask
. The following example, that stops the time going, uses only CountDownTimer
without Timer
and TimerTask
. I simplified the code a bit for the sake of brevity.
private CountDownTimer timer;
private TextView txtProgress;
private Button stopButton;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtProgress = findViewById(R.id.tv);
timer = new CountDownTimer(30000, 500) {
public void onTick(long millisUntilFinished) {
handler.post(() -> {
txtProgress.setText("any text");
});
}
public void onFinish() { }
}.start();
findViewById(R.id.stopButton).setOnClickListener(v -> timer.cancel());
}