0

我需要每隔一段时间执行一次代码,有时是 10 秒,有时是 5 分钟。代码应在开始后的 10 秒处执行,然后在开始后5 分 10 秒处执行,等等 。计时表从开始处开始滴答作响,因此执行时间必须准确

使用Handler.postDelayed不起作用,因为要执行的代码可能需要一些时间。发生这种情况时,代码的下一次执行可能会延迟。

当我想实施AlarmManager时,我看到了注释

警报管理器适用于您希望应用程序代码在特定时间运行的情况,即使您的应用程序当前没有运行。对于正常的计时操作(滴答声、超时等),使用 Handler 更容易、更高效。

所以我有点困惑,我应该怎么做才能保证正确执行?

4

5 回答 5

1

看看这篇文章:时间/日期更改监听器。您可以使用 setRepeating() 方法,或者在每次执行后再次设置计时器。

于 2012-06-24T17:22:33.443 回答
1

由于 android 不是硬实时操作系统,因此如果不进行大量内核修改,就不可能获得准确的执行时间。即使在那里,您也不太可能在典型的 android 设备上以精确定时的方式提供有用的 I/O,因此仅在完美的时间运行您的代码可能还不够。

充其量您可以使用更可靠的计时器确定您的代码可以运行的最新时间点,并采取事后补偿措施。

就可用的计时方法而言,主要考虑的应该是您是否打算将设备从睡眠中唤醒以完成事件,在这种情况下您应该使用警报管理器,如果您打算让设备保持清醒,在这种情况下您应该使用唤醒锁,或者如果您对仅在设备唤醒并且您的服务或活动正在运行时发生的事件感到满意,在这种情况下您可以使用简单的计时器。

于 2012-06-24T17:54:30.767 回答
1

正如 Chris 所说,Android 中没有确切的时间。

但是你可以尝试这样接近实时......

等待5s的一些伪代码:

class mJob implements Runnable{
   public void run(){
      while(System.currentTimeMillis()<myExactTime){ //poll for your time
         Thread.sleep(1);
      }
      //Ok, we are as near as we'll ever get
      //call here your 'realtime' function or whatever you need
   }
}

 mHandler.postDelayed(mJob,4950); //the closer to 5000, the better for the cpu but you could miss your `myExactTime`

我现在不知道这有多准确,你只需要尝试一下。但我认为没有其他方法可以使用普通 SDK 变得更加“实时”。您甚至可以删除sleep(1)以变得更接近您的myExactTime.

对于下一次通话,请使用以下内容(从头开始):

nextCallDelayInMillis = starttimeInMillis+No1_Delay+No2_Delay-System.currentTimeMillis();

于 2012-06-24T18:09:37.030 回答
1

您没有指定您的代码是在应用程序运行时运行还是作为后台服务运行。这很重要,因为在您锁定设备后,Android 会进入睡眠模式,此时 CPU 处于关闭状态,并且不会激活 postDelayed 等功能。意图也要求开始活动。但是 AlarmManager 广播会。我将从这里引用

AlarmManager 最适合用于即使在应用程序未打开时也需要运行的任务。对于需要在应用程序使用期间运行的正常计时操作(滴答声、超时等),使用 Handler 的 postDelayed() 和 postAtTime() 方法效率更高。AlarmManager 需要太多开销来证明以这种方式使用它是合理的。

于 2014-07-24T11:16:49.223 回答
0

我建议您使用 postDelay,对于处理程序的任何发布,处理程序正在打开新线程并且代码正在同时执行。

private Runnable mUpdateTimeTask = new Runnable() {
public void run() {

//some code

mHandler.postDelayed(this, 1000);
}
};

这是我使用 postDelay 显示倒数计时器的完整代码:https ://github.com/minimaldevelop/antistress/blob/master/src/com/minimaldevelop/antistress/AntiStressExerciseActivity.java

同样在这里,我使用 AlarmManger,但仅作为在应用程序关闭时在通知栏中显示消息的剩余部分。

于 2012-06-24T17:50:01.657 回答