1

私の問題はこれです: 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);
}
4

1 に答える 1

2

Each time you post some task or send some message this objects are added to a queue. When you call removeCallbacksAndMessages this queue is cleaned. But tasks or messages that are being dispatched (already pulled from queue) when you call removeCallbacksAndMessages will not be cancelled. If you want to stop a task do it as a thread:

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;
    }
}

EDIT:

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;
        }
    };
} 

So you can add this cancel option into your handler. When message arrives handler will execute this code and if during execution you call cancel() method handler will halt whatever he was doing on while.

于 2012-06-26T10:46:02.587 に答える