2012-06-25 2 views
3

Я пытаюсь использовать вложенные postDelayed, потому что мне нужно что-то сделать после (задержка на) 5 минут, остановить его после (задержка) 30 секунд, сделать что-то еще, а затем повторить оба события в цикл снова с самого начала. Я просто не могу понять.Вложенные postDelayed/Runnable/Handler Android

код у меня есть ГНФАР:

private long EnabledAfter = 300000; // 5 minutes 
private long DisabledAfter = 30000; // 30 seconds 

public void start_timers(){ 
    on_delayed(EnabledAfter); 
}//end method 

private void on_delayed(long period_off){  
    Delayed = new Runnable() { 
     public void run() {              
      something.enable(context);       
      something.enable_else(context, true);  
      off_delayed(DisabledAfter); // and disable both again delayed 

      Handler.postDelayed(Delayed, EnabledAfter); 
     } 
    }; 
    Handler.postDelayed(Delayed, EnabledAfter); 
}//end method 

private void off_delayed(long period_on){  
    Delayed = new Runnable() { 
     public void run() { 
      something.disable(context);         
      something.disable_else(context, false); 
      on_delayed(period_on); // start the proces again from the start... 

      //Handler.postDelayed(Delayed, DisabledAfter);    
     } 
    }; 
    Handler.postDelayed(Delayed, period_on); 
}//end method 

Проблема с этим прекрасно работает первый запуск, но потом, кажется, укладывают друг на друга ... и все задержки BORKED. Мне нужно выполнить как Runnable s ровно 5 минут и 30 секунд, а затем повторить процесс.

ответ

6

Конечный результат после того, как этот код пропустил несколько раз, заключается в том, что сообщения Handler отправляют слишком много экземпляров каждого из Runnable. Как написано выше:

  1. Первого on_delayed сообщения 1 Runnable
  2. Это Runnable пожары, а затем сообщения 2 Runnables (один в off_delayed, и еще до возвращения из бега()).
  3. Это будет продолжать увеличиваться, потому что, когда эти два Runnables fire, 4 будут созданы, так далее.

Вы также не можете воспользоваться тем фактом, что Runnable может быть отправлен в одну очередь несколько раз, поэтому его не нужно создавать каждый раз. Это необходимо, если вы хотите отменить действия, потому что метод remove на Handler ищет все соответствующие экземпляры для удаления из очереди. Вы могли бы попробовать что-то вроде этого, вместо:

private long EnabledAfter = 300000; // 5 minutes 
private long DisabledAfter = 30000; // 30 seconds 

private Runnable Enabler = new Runnable() { 
    public void run() {              
     something.enable(context);       
     something.enable_else(context, true);  

     Handler.postDelayed(Disabler, DisabledAfter); 
    } 
}; 

private Runnable Disabler = new Runnable() { 
    public void run() { 
     something.disable(context);         
     something.disable_else(context, false); 

     Handler.postDelayed(Enabler, EnabledAfter);    
    } 
}; 

public void start_timers(){ 
    Handler.postDelayed(Enabler, EnabledAfter); 
}//end method 

public void stop_timers(){ 
    Handler.removeCallbacks(Enabler); 
    Handler.removeCallbacks(Disabler); 
}//end method 

Я также добавил еще один метод можно использовать для отмены операции таймера, удалив все экземпляры ваших Runnable элементов из очереди.

HTH

+0

mmm, спасибо, это работает! Почему, почему я не подумал об этом? Спасибо за помощь! – slinden77

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