繁体   English   中英

处理程序 postDelayed 执行几次

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM