2012-06-26 24 views
1

我的問題是這樣的:我使用Handler.postDelayed()500毫秒後運行動畫。後來在代碼中,我使用Handler.removeCallbacksAndMessages()導致有時我想運行另一個動畫。問題是,有時第一個動畫開始但未完成,我認爲這是同步問題。android postDelayed和removeCallbacksAndMessages同步

有沒有辦法來檢查是否啓動給postDelayed()的Runnable,並在這種情況下取​​消removeCallbacksAndMessages()?

如果從此Runnable開始運行(),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); 
} 

回答

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()方法處理程序將暫停他正在執行的任何操作。

+0

好的,謝謝。但是,如果這條消息從隊列中拉出,我現在怎麼辦?這是我的主要問題。因爲調用removeCallbacksAndMessages()是沒有意義的,如果消息已經發出... – newman555p

+0

您可以在我的答案中看到解決方案。基本上這樣做,但認爲現在執行在handleMessage()上。 –

+0

對不起,但我不明白。我知道Handler有消息系統,甚至看着hasMessage()方法來檢查我的消息是否仍在隊列中,但hasMessage()需要一些消息ID,我不明白它是什麼。如果你看看我的例子,有沒有一種方法可以在調用removeCallbacksAndMessages()之前檢查我的排隊Runnable是否被拉出? 對不起,如果你已經回答了我的問題,我只是無知而無法忍受它。順便說一句,我讀過類API,但仍然沒有運氣......感謝您的幫助和耐心。 – newman555p