2012-06-26 3 views
1

моя проблема в следующем: я использую Handler.postDelayed() для запуска анимации после 500 мс. Позже в коде я использую Handler.removeCallbacksAndMessages(), потому иногда я хочу запустить другую анимацию. Проблема в том, что иногда первая анимация запускается, но не завершается, и я думаю, что это проблема синхронизации.android postDelayed and removeCallbacksAndMessages sync

Есть ли способ проверить, запущен ли Runnable для postDelayed() и в этом случае отменить removeCallbacksAndMessages()?

Если запущен run() из этого Runnable, удаляетCallbacksAndMessages?

Код что-то вроде этого:

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

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

Таким образом, вы можете добавить эту опцию отменить в обработчик. Когда сообщение приходит, обработчик выполнит этот код, и если во время выполнения вы вызовете метод cancel(), то обработчик остановит все, что он делал.

+0

Хорошо, спасибо. Но как мне теперь, если это сообщение вытащили из очереди? Это моя главная проблема. Поскольку вызов removeCallbacksAndMessages() бессмысленен, если сообщение уже отправлено ... – newman555p

+0

Вы можете увидеть на моем ответе решение. В основном делайте то же самое, но думайте, что теперь выполнение выполняется на handleMessage(). –

+0

Извините, но я не понимаю. Я понимаю, что у Handler есть система сообщений, и даже посмотрел на метод hasMessage(), чтобы проверить, остается ли мое сообщение в очереди, но hasMessage() требует некоторого идентификатора сообщения, что я не понимаю, что это такое. Если вы посмотрите на мой пример, есть ли способ, чтобы я мог проверить, потянут ли моя очередь Runnable до вызова removeCallbacksAndMessages()? Извините, если вы уже ответили на мой вопрос, и я просто не знаю, как его раскрыть. Кстати, я прочитал API класса, но все равно не повезло ... Спасибо за вашу помощь и терпение. – newman555p

Смежные вопросы