[英]Handler postDelayed executes few times
我的用户界面上有一个 SeekBar。 当我改变它的位置时,我想在 TextView 中报告它的值。 在这个 TextView 中,我还想提供一个信息,位置仍然是多长时间(以秒为单位)。 我想,Runnable 中的 run 方法只会运行一次,但每次 postDelayed 执行它都会运行几次。 无论延迟是 1 秒还是 10 秒。 如何强制它只运行一次? 我应该做一个线程吗?
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
y=0;
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
myHandler.postDelayed(this, 1000);
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" + progressX.getMax() + " position is still for " + y + " seconds");
y+=1;
}
},1000);
}
编辑:removeCallbacks 有点帮助。 代码工作正常,但现在只在第一个 progressChange 上,我明天会试着弄清楚。
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
y=0;
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
myHandler.removeCallbacks(this);
y+=1;
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" + progressX.getMax() + " position is still for " + y + " seconds");
myHandler.postDelayed(this, 5000);
}
},5000);
}
问题是, onProgressChanged的每个事件同时运行新的 runnable。 将myHandler.removeCallbacks(runnable)放在run方法中,产生了一点积极的效果,它是唯一“正确”工作的地方。 实际上, y增加得非常快,通过我们之前和当前搜索栏位置的 delta 值( postDelayed方法的累积),然后每秒增加 1。 removeCallbacks 终止了之前的postDelayed操作。
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
y=0;
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
myHandler.removeCallbacks(runnable);
...
y+=1;
runnable=this;
myHandler.postDelayed(runnable, 1000);
}
},1000);
但是,这就是解决方案,将myHandler.removeCallbacksAndMessages(null)放在onProgressChanged 中有所帮助。 我附上代码以便更好地理解。 TextView progressIndicator显示,您在搜索栏的当前位置停留多长时间(以秒为单位)。
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
myHandler.removeCallbacksAndMessages(null);
y=0;
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" +
progressX.getMax());
myHandler.postDelayed(new Runnable(){
@Override
public void run(){
y+=1;
progressIndicator.setText("Covered: " + progressX.getProgress() + "/" +
progressX.getMax() + " position is still for " + y + " seconds");
runnable=this;
myHandler.postDelayed(runnable, 1000);
}
},1000);
您基本上是在使用一种模式来永远重复Runnable
。 在您的Runnable
,您可以调用mHandler.postDelayed(this, 1000);
. 在this
在这方面是new Runnable
您最初创建的。 这意味着Runnable
将在每次执行时在一秒后安排另一次运行。
如果你只希望它运行一次,你应该删除mHandler.postDelayed(this, 1000);
线。
您还应该确保在onDestroy()
调用mHandler.removeCallbacks(null)
以确保不会导致内存泄漏,因为您的Runnable
将通过TextView
引用保存对您的Activity
的引用。
当搜索栏移动时, onProgressChanged
被调用几次,这意味着您有几个待处理的postDelayed()
为了解决这个问题,每次调用postDelayed()
都应该先调用removeCallbacks()
以确保只有一个挂起的postDelayed()
将处于活动状态
但是您需要在类字段中创建 Runnable 和 Handler 实例,而不是在onProgressChanged
主体上
像这样的东西:
private Handler myHandler = new Handler();
private Runnable myRunnable = new Runnable() {
@Override
public void run() {
// do something //
myHandler.removeCallbacks(myRunnable);
myHandler.postDelayed(myRunnable, 1000);
}
};
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// do something //
myHandler.removeCallbacks(myRunnable);
myHandler.postDelayed(myRunnable, 1000);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.