removeCallbacks不会停止runnable

时间:2011-04-30 20:03:50

标签: android runnable

我是通过一种方法来调用的:

myHandler.postDelayed(mMyRunnableHide, 6000);

调用:

public Runnable mMyRunnableHide = new Runnable()
{

    public void run()
    {
        mTextDisplay.setText("");
        DisplayX();
    }
 };

如果单击屏幕上的按钮,我想停止运行:

   Button next = (Button) findViewById(R.id.Breaction);
    next.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {

            myHandler.removeCallbacks(mMyRunnableHide);

            mTextDisplay.setText("");
            DisplayX();
            }
        });   
    }

removecallbacks没有停止runnable。我究竟做错了什么?我使用的方法是否正确?我只是希望当用户点击按钮时,runnable为“Not Run”。

感谢您的帮助。

5 个答案:

答案 0 :(得分:34)

在我看来,removeCallbacks(..)仅停止待处理的消息(Runnables)。如果你的runnable已经启动,那么就没有停止它(至少不是这样)。

或者,你可以扩展Runnable类并给它一些像这样的kill开关:

public class MyRunnable implements Runnable
{
   private boolean killMe = false;

   private void run()
   {
      if(killMe)
         return;

      /* do your work */
   }

   private void killRunnable()
   {
      killMe = true;
   }
}

这只会阻止它启动,但你偶尔可以检查killMe并挽救。如果你正在循环runnable(比如某种后台线程),你可以说:

while(!killMe) {
   /* do work */
}

希望这有帮助

编辑我只想发布此更新。自从这篇原创帖子以来,谷歌已经推出了一个名为AsyncTask的优秀课程,可以为你处理所有这些内容。任何读这篇文章的人都应该深入研究它,因为这是正确的做事方式。

您可以阅读here

答案 1 :(得分:12)

Handler.removeCallback是同步的,并且可以很好地提供:

  1. 您总是在主线程中致电postDelayed
  2. 您总是在主线程中致电removeCallback
  3. 删除回调后,您不会再次致电postDelayed
  4. 所以在你的情况下,removeCallbacks是从一个按钮处理程序调用的,它在主线程中运行。但是您没有在代码中显示您调用postDelayed的位置。如果你从后台线程中调用它来解决问题所在。

    如果你确定你没有从后台线程调用这些方法中的任何一个,并且调用的顺序是正确的,那么由于配置更改(屏幕旋转)上的活动重新创建,你可能会无意中保留未被删除的任务等)。务必务必再次使用removeCallbacks方法拨打onDestroy以防止出现此类问题。

答案 2 :(得分:7)

这是完成mtmurdock描述的另一种方法。该类允许在Runnable被定义为匿名内部类的任何类中编辑实例变量。

package support;

/**
* Runnable that can be stopped from executing
*/
public abstract class KillableRunnable implements Runnable{

private boolean isKilled=false;

/**
 * Instead of Overriding run(), override this method to perform a Runnable operation. 
 * This will allow editing instance variables in the class that this Runnable is defined
 */
public abstract void doWork();

//The handler that posts this Runnable will call this method. 
//By default, check if it has been killed. doWork() will now be the method 
//override to implement this Runnable
@Override
final public void run(){
    if(!isKilled){
        doWork();
    }
}

final public void kill(){
    isKilled=true;
}
}

答案 3 :(得分:0)

我不认为removeCallbacks(..)仅停止待处理的消息(Runnables),我认为removeCallbacks(..)无法正常工作还有其他原因,但我不知道。因为postDelayed(..)和removeCallbacks(..)在同一线程中

答案 4 :(得分:0)

以下对我有用。将其放在onResume中。

mService= null;

public void onServiceConnected(ComponentName name, IBinder service) {
        Log.i(TAG, "OnServiceConnected");
        ContadorFG.LocalBinder binder = (ContadorFG.LocalBinder) service;
        mService = binder.getService();
        connected = true;
        synchronized (lock){
            lock.notifyAll();
        }
    }

public void onResume() {
    super.onResume();
    loopDelayed();
}  

private void loopDelayed(){ 
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            if (mService != null) {

                ----
                ----
                ----

                return;
            }else{
                //auto call 
                loopDelayed();
            }
        }
    }, 10);

}