AlarmManager的setRepeating和setInexactRepeating之间的区别

33

以下是参数的定义:

alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_FIFTEEN_MINUTES, alarmIntent);

以下是其中的:

alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

这两者有何不同,且在功能方面又如何区别?

5个回答

39

这两个示例都安排了一个重复的闹钟,将发送给给定的 alarmIntent。在两种情况下,第一次发送的时间将是立即的(calendar.getTimeInMillis() 返回 当前时间)。在这两种情况下,当需要发送闹钟时会唤醒设备(如 AlarmManager.RTC_WAKEUP 所示)。

这些调用之间有两个区别。更简单的一个是,第一个调用将每十五分钟发送一次意图,而第二个调用将每天发送一次意图(如您在第三个参数中所看到的)。更复杂的差异是函数调用本身:setRepeating 将精确地为前十五分钟安排第一个闹钟;setInexactRepeating 将不精确地为约 24 小时安排第二个闹钟,这意味着它可能偏离该间隔 - 带有消耗较少电力的优势。

请注意,这在 API 19 中已发生变化,这两个调用是同义词。请参见 此指南此 API 文档


如果我针对SDK 18进行开发,而我的最大SDK版本是19,那么我需要分别为两个版本编写代码吗? - User3
如果我绑定了一个服务在闹钟触发后被调用,我需要获取唤醒锁吗? - User3
是否分别为两种情况编写代码取决于您的需求。我可以告诉您的是,只有在targetSdkVersion为19时,setRepeating()的行为才与setInexactRepeating()的行为相匹配。对于任何较低的targetSdkVersion,它们的行为都不同。 - PaF
1
在给定的“alarmIntent”上下文中,设备将保持唤醒状态。如果您要离开上下文,则设备可能会回到睡眠状态。因此,例如,如果您的“alarmIntent”启动一个活动,则可以确定设备将保持唤醒状态以处理意图。但是,如果您随后想通过调用“startService()”从活动中启动服务,则必须获取唤醒锁以确保服务将启动。请参见此处的示例 - PaF

20

确定您的闹钟需要多精确

在创建闹钟时,选择闹钟类型通常是第一步。更进一步的区别是您需要多精确的闹钟。

对于大多数应用程序来说,setInexactRepeating()是正确的选择。当您使用此方法时,Android会同步多个不精确重复的闹钟并同时触发它们。这可以减少电池的消耗。

对于那些有严格时间要求的罕见应用程序,例如闹钟需要每天精确地在下午4:00 触发,则使用setRepeating()

参考:确定您的闹钟需要多精确


非常好的解释,特别是关于 setRepeating()。谢谢。 - Muhammad Saqib

9
为了补充之前的答案,使用重复闹钟时需要考虑一些其他最佳实践,特别是使用setInexactRepeating()请求的不精确闹钟。 闹钟类型
  • 从电源管理的角度来看,非唤醒(Non-WAKEUP)闹钟比唤醒(WAKEUP)闹钟更好。如果使用前者,你的闹钟可能会晚点触发,但在设备被用户唤醒或其他唤醒闹钟触发时仍会触发。使用唤醒闹钟将唤醒设备,消耗额外的电池,并可能导致其他延迟的不精确闹钟触发,这些闹钟本来可以进一步延迟(减少不精确闹钟提供的批处理节能优势)。
  • 相对于RTC时间基准,最好使用ELAPSED时间基准的闹钟。前者在各个设备上的分布更随机,这降低了网络拥塞和服务器端的风险,尤其是如果闹钟触发某种轮询。运行Gingerbread(或更早版本)的手机存在一个错误,即RTC不精确闹钟有倾向于与实时时钟紧密对齐,例如每个小时的大约30秒。在这些早期平台版本上,ELAPSED闹钟不会受到此错误的影响。即使你的闹钟没有触发任何网络活动,也要记住,如果它是唤醒闹钟,它可能会触发其他非唤醒意图的闹钟,这些闹钟可能会连接到网络。
时间基准
  • 注意为闹钟类型正确指定请求的开始时间。如果未能这样做,将导致闹钟被设置在过去(它们立即触发),如果使用ELAPSED时间基准设置RTC闹钟,则会在未来很长时间内触发ELAPSED闹钟。你可以通过adb shell使用dumpsys alarm检查应用程序已安排的闹钟。
间隔
  • 在SDK <19上,指定除AlarmManager API中定义的间隔常量以外的不精确闹钟间隔是多余的:它们将被安排为精确而不是不精确闹钟,失去了不精确闹钟提供的所有节能优势。
编辑:这里有关于Gingerbread和Honeycomb 3.0设备的错误的进一步解释:https://code.google.com/p/android/issues/detail?id=31550

4

setRepeating 更加准确,而setInexactRepeating则是为了节省电量但不够准确。setInexactRepeating适用于后台维护,例如闹铃,而setRepeating则对于像闹钟这样的例子是必要的。


0

当应用程序不需要严格要求例如早上起床时使用 setInexactRepeating()。如果闹钟大约在那个时间唤醒,就没有任何生命危险了。 像药品应用程序一样,高度关键的患者使用该应用程序提醒护士或医生工作人员必须使用setRepeating()。 当您使用setInexactRepeating()时,Android会从多个应用程序同步重复的警报,并在同一时间(一次)触发它们。这减少了系统必须唤醒设备的总次数,从而减少了电池的消耗。 重复的警报是不精确的。请注意,尽管setInexactRepeating()比setRepeating()有所改进, 但如果每个应用程序实例在同一时间击中服务器,它仍然可能会压倒服务器。因此,对于网络请求,请为您的警报添加一些随机性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接