android postDelayed和removeCallbacksAndMessages同步

时间:2012-06-26 10:17:06

标签: android multithreading handler sync runnable

我的问题是:我使用Handler.postDelayed()在500ms后运行动画。稍后在代码中我使用Handler.removeCallbacksAndMessages()导致有时我想要运行另一个动画。问题是有时第一个动画开始但没有完成,我认为这是同步问题。

有没有办法检查是否启动了给postDelayed()的Runnable,在这种情况下取​​消removeCallbacksAndMessages()?

如果启动runnable的run(),removeCallbacksAndMessages有效吗?

代码是这样的:

Handler hand = new Handler();
if (counter==2) {
    one = (ImageView) findViewById(img_id);
    two = im;
    hand.postDelayed(new Runnable() {
        public void run() {
    applyAnim(0, 90, one, false);
    applyAnim(0, 90, two, false);
    counter = 0;
        }
    }, 750);
} else (counter == 3) {
    im.setClickable(false);
    hand.removeCallbacksAndMessages(null);
    counter = 1;
    applyScndAnim(0, 90, one, false);
    applyScndAnim(0, 90, two, false);
}

1 个答案:

答案 0 :(得分:2)

每次发布​​某个任务或发送一些消息时,此对象都会添加到队列中。当您调用removeCallbacksAndMessages时,将清除此队列。但是,当您调用removeCallbacksAndMessages时,正在调度(已从队列中拉出)的任务或消息将不会被取消。如果要停止任务,请将其作为线程执行:

public class DrawableTask implements Runnable{
    private boolean cancel = false;
    private boolean isBeingDispatched = false;
    public void cancel(){
        if (this.isBeingDispatched())
            this.cancel = true;
    }
    public boolean isBeingDispatched(){ return isBeingDispatched;}
    public void run(){
        isBeingDispatched = true;
        while(!cancel){
            //refresh 
        }
        cancel = false;
        isBeingDispatched = false;
    }
}

编辑:

private boolean cancel = false;
private boolean isBeingDispatched = false;

public void cancel(){
    if (this.isBeingDispatched())
        this.cancel = true;
}
public boolean isBeingDispatched(){ return isBeingDispatched;}

public void setHandlers(){
    Handler handler = new Handler(){
        public void handleMessage(Message msg){
             YourClassName.this.cancel = false;
             YourClassName.this.isBeingDispatched = true;
             while(! YourClassName.this.cancel){

                  //refresh
             }
             YourClassName.this.cancel = false;
             YourClassName.this.isBeingDispatched = false;
        }
    };
} 

因此,您可以将此取消选项添加到处理程序中。当消息到达时,处理程序将执行此代码,如果在执行期间调用cancel()方法处理程序将停止他正在做的任何事情。