java - 单击停止按钮后 TimerTask 没有停止
问题描述
所以我点击一个开始按钮,每一秒我都会通过计算时间来更改标签的文本:
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();
单击停止按钮后progressBar
停止旋转,这是正确的,但时间不断增加,我做错了什么?请注意,这个问题在我用来测试它的手机上不存在,但它存在于平板设备上,也许它们处理线程的方式不同?
此处停止计时器的代码:
stopclicked = true
if(hasStartedtt2 == true) {
tt2.cancel();
// handler.removeCallbacksAndMessages(null);
}
if (T2 != null) {
T2.cancel();
T2.purge();
}
pStatus = 101;
EDIT1:我刚刚注意到它已停止,但在我单击停止后仅 20 - 25 秒,是什么导致了延迟?
解决方案
时间不会停止的原因(或“在您单击停止后仅 20-25 秒”停止)是您在每个'sT2 = new Timer()
上创建的新实例。旧的实例并继续驻留在Java堆上,直到被垃圾收集为止。您可能会注意到时间变化是颠簸的。tt2 = new TimerTask()
CountDownTimer
onTick()
Timer
TimerTask
此外,您似乎使任务实现过于复杂。你可能不需要Timer
也不需要TimerTask
。以下示例停止了时间的流逝,仅CountDownTimer
在没有Timer
and的情况下使用TimerTask
。为了简洁起见,我稍微简化了代码。
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());
}
推荐阅读
- javascript - 实时添加节点时D3动态网络慢
- mysql - Kubernetes Galera:WSREP:无法打开 gcomm 后端连接:110:
- java - 如何在子类中更改超类的变量类型?
- vba - VBA 选项按钮真、假或空
- xml - Ironpython 使用 xmlns 读取 XML
- c# - Nancy Autofac 防止容器处置
- gremlin - Gremlin Python 如何使 by(values('name','score')) 工作
- mcmc - 运行 Jags - 从 mcmc 对象中提取多个实现
- java - JavaFX TreeTableView 图像伪影
- java - 我尝试将 Spring 的默认记录器更改为 log4j2 有什么问题?