我需要每隔一段时间执行一次代码,有时候是10秒,有时是5分钟。代码应该从完全开始10秒后执行,然后在完全开始5分10秒后执行等。
计时器从一开始就在滴答作响,因此执行时间必须准确。
使用Handler.postDelayed
不起作用,因为要执行的代码可能需要一些时间。当发生这种情况时,代码的下一次执行可能会延迟。
当我想要实现AlarmManager
时,我看到了注释
警报管理器适用于您想要的情况 应用程序代码在特定时间运行,即使您的应用程序是 目前没有运行。对于正常的计时操作(刻度,超时, 等)使用Handler更容易,也更有效。
所以我有点困惑,我该怎么做才能保证正确的执行?
答案 0 :(得分:1)
看一下这篇文章:Time/Date change listener。你可以使用setRepeating()方法,或者在每次执行后再次设置定时器。
答案 1 :(得分:1)
由于android不是硬实时操作系统,如果没有实质性的内核修改,确切的执行时间是不可能的。即使在那里,你不太可能在典型的Android设备上有很多方法来确切地计算有用的I / O,所以只是在完美的时间运行你的代码可能还不够。
充其量,您可以使用更可靠的计时器来确定您的代码可以运行的最新点,并采取事后补偿措施。
就可用的定时方法而言,主要考虑因素是如果您打算将设备从睡眠状态唤醒以完成事件,在这种情况下,如果您打算保持设备处于唤醒状态,则应使用警报管理器,其中如果您使用唤醒锁,或者只有当设备处于唤醒状态并且您的服务或活动正在运行时才发生您的事件,那么您可以使用简单的计时器。
答案 2 :(得分:1)
正如克里斯所说,在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();
答案 3 :(得分:1)
您没有指定代码是在应用程序运行时运行还是作为后台服务运行。这很重要,因为在您锁定设备后,Android会进入睡眠模式,此时CPU处于关闭状态且postDelayed等功能将无法激活。想要开始活动的意图。 但是AlarmManager广播会。 我引用here
AlarmManager最适合需要的任务 即使应用程序未打开也会运行。用于正常的定时操作 需要在应用程序使用期间运行(滴答,超时等),它是 使用postDelayed()和postAtTime()方法更有效率 处理程序。 AlarmManager需要太多的开销来证明它的合理性 以这种方式使用。
答案 4 :(得分:0)
我建议你使用postDelay,对于任何post to handler,handler都是打开新线程并且代码同时执行。
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,但仅作为剩余部分在应用程序关闭时在通知栏显示消息。