4

我正在尝试使用嵌套的 postDelayed 因为我需要在(延迟)5 分钟后做某事,在(延迟)30 秒后停止它,做其他事情,然后从头开始再次重复循环中的两个事件。我似乎无法做到正确。

我到目前为止的代码:

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

这样做的问题是第一次运行良好,但随后似乎堆叠在彼此之上......并且所有延迟都被破坏了。我需要Runnable在 5 分 30 秒内执行这两个 s,然后重复该过程。

4

1 回答 1

8

这段代码运行几次后的最终结果是Handler每个Runnable. 如上所写:

  1. 第一个 on_delayed 帖子 1 可运行
  2. 该 runnable 触发,然后发布 2 个 Runnable(一个在 off_delayed 中,另一个在从 run() 返回之前)。
  3. 这将继续增加,因为当这两个 Runnable 触发时,将创建 4 个,依此类推。

您也没有利用 aRunnable可以多次发布到同一个队列的事实,它不必每次都创建新的。如果您想取消操作,这是必不可少的,因为 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从队列中删除项目的所有实例来取消计时器操作。

高温高压

于 2012-06-25T22:03:28.327 回答