我应该使用AlarmManager还是Handler?

16

我正在编写一个应用程序,它会不断轮询设备的传感器,并且每隔一段时间需要将一些统计信息写入文件。这可能快到每秒一次,也可能慢到每分钟一次。我应该使用 HandlerpostDelayed() 方法还是仅使用 AlarmManager 进行安排?

4个回答

25

这应该帮助您区分HandlerAlarmManager【来源】

尽管人们认为这些主要适用于API 23,但它是一个新版本。

后台工作、闹钟和您的 Android 应用程序的流程图


16
如果应用程序应在待机状态下工作,则使用 AlarmManager。如果不需要,则使用 Handler
AlarmManager 会唤醒 CPU,因此会更耗电,而 Handler 在待机状态下无法工作。

1
手机何时进入睡眠模式?我已经测试了我的应用程序一段时间了,设备进入待机状态从来没有成为问题。 - Moises Jimenez
2
我刚刚发现了更详细的类似答案:https://dev59.com/iW435IYBdhLWcg3w9E9Y#5120225。 - pawelzieba

13

根据以下关键点决定你的设计:

AlarmManager: AlarmManager的优点是即使设备处于深度睡眠模式(CPU关闭),它也能工作。当警报触发时,它会击中BroadcastReceiver,并在onReceive中获取唤醒锁(如果你使用了WAKEUP类型的警报,如RTC_WAKEUPELAPSED_TIME_WAKEUP)。在完成onReceive()之后,它会释放唤醒锁。

但大多数情况下,它对我来说都不起作用。因此,在onReceive()中,我已经自己获取了唤醒锁,并在最后释放它们,以确保我真正获得了CPU。

原因是当多个应用程序同时使用资源(例如可以防止系统挂起的唤醒锁)时,框架会在这些应用程序之间分配CPU消耗,但不一定均匀。因此,如果很重要,最好获取唤醒锁并完成任务。

计时器和Handler: Handler和计时器不能在深度睡眠模式下工作,这意味着当设备处于睡眠状态时,任务/可运行项将不会按计划运行。它们不计算睡眠时间,这意味着分配给执行任务的延迟仅在活动模式下计算。因此,实际延迟将是延迟给定的时间 + 在深度睡眠中花费的时间。


谢谢。能否展示一下如何获取自己的唤醒锁的示例会很好。在stackoverflow上有很多关于定时器或按间隔执行操作的帖子,但我一直无法通过AlarmManager、Handler、BackgroundServices或Sleeps实现一致的效果:P我还没有尝试过的唯一一件事是在这里解释的 https://stackoverflow.com/a/11177974 - San Jay

2

我认为这取决于轮询间隔。我猜你的轮询间隔相当低(大约几秒钟),因此你应该采用Handler方法或使用Timer类。

AlarmManager是一个更高级别的服务,它涉及更大的开销来处理这个用例。当闹钟触发时,你需要使用BroadcastReceivers来处理它。这意味着每次处理这些闹钟时,你需要注册对你感兴趣的传感器的监听器,这在我看来极其低效。


我查看了计时器文档,计时器作为守护线程运行是什么意思?它是一个服务吗? - Moises Jimenez

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