2012-06-25 5 views
3

5 분 후 (지연) 30 초 후 멈추고 다른 작업을해야하기 때문에 중첩 된 postDelayed를 사용하려고합니다. 다시 시작부터주기. 나는 그것을 올바르게 이해하지 못하고있다. 내가 SOFAR이중첩 된 postDelayed/Runnable/Handler 안드로이드

코드 :이와

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된다. 나는 정확히 5 분 30 초에 Runnable을 모두 실행해야하며 그 과정을 반복합니다.

답변

6

이 코드를 실행 한 후의 최종 결과는 Handler이 각 Runnable의 인스턴스를 너무 많이 게시한다는 것입니다. 위의 기록으로 :

  • 1의 Runnable

    1. 먼저 on_delayed 게시물 그 다음 실행 가능한 화재 게시물이 개보다 Runnable (실행에서 반환하기 전에 off_delayed 하나, 또 다른를()).
    2. 두 개의 Runnables이 실행될 때 4가 생성되고, 그렇게되면 계속됩니다.

    Runnable을 동일한 대기열에 여러 번 게시 할 수 있다는 장점을 이용하지 않으며 매번 새로운 메시지를 만들 필요가 없습니다. Handler의 remove 메소드가 일치하는 모든 인스턴스를 대기열에서 제거하기 때문에 조치를 취소하려면 필수적입니다. 이 대신 같은 것을 시도 할 수 있습니다 :

    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

    음, 감사합니다. 왜 왜 이런 생각을 못했을까요? 도와 줘서 고마워! – slinden77