android postDelayed и removeCallbacksAndMessages sync

1

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

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

Если run() из этого Runnable запущен, does 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);
}
Теги:
multithreading
handler
runnable
sync

1 ответ

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 () бессмысленно, если сообщение уже отправлено ...
  • 0
    Вы можете увидеть на мой ответ решение. В основном делайте то же самое, но думайте, что теперь выполнение находится на handleMessage ().
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню