当CPU休眠时,Handler的postDelayed方法是否会失效?

20
我有一个带有一些`Handlers`的活动,这些处理程序以不超过5分钟的间隔执行。该活动是从`BroadcastReceiver`启动的,并且可能在屏幕关闭时等待用户抓取电话并获取用户输入,当这种情况发生时,活动的`onPause()`被调用,因此CPU肯定处于睡眠模式。我没有设置活动来打开屏幕,因为我想尽可能节省电量。
我已经通过我的手机进行了测试,而且效果非常好,当屏幕关闭时,所有的`Handlers`都会执行它们需要运行的所有代码。如果我在活动打开时打开和关闭屏幕,一切都正常工作。
现在,我已经到处阅读,当屏幕关闭并且CPU处于睡眠状态时,某些设备的表现并不如预期,大多数时候与加速计有关。现在我的问题是,在我的活动打开时,是否需要获取`WakeLock`,以便CPU不会进入睡眠状态?我真的想知道这一点,因为我之前说过,我不想通过获取昂贵的`WakeLock`浪费电池电量。
我更喜欢一个详细回答这个问题的人,他确实知道这是如何工作的。

你为什么要使用Activities来执行后台任务?Activity用于显示内容而不是运行任务。你有考虑过使用Services吗? - tolgap
不不,这个活动并不执行后台任务。它是一个通过广播接收器打开的活动,等待用户查看手机并进行操作,但我不想添加KEEP_SCREEN_ON标志,所以有时候活动在屏幕关闭的情况下打开(或者在活动打开时屏幕关闭)。 - Jorge Fuentes González
1个回答

27

你的方法无法稳定实现目标。如果使用Handler的postDelayed()方法且CPU进入深度睡眠,ms计数器将停止,并且只有在CPU再次唤醒时才会继续计数。

点击这里了解更多详情。

如果你想要一种类似于cron job的方式,你需要使用wakelock。幸运的是,有一种Service实现正好做到了这一点:Wakeful IntentService

引用文档:

Android中等同于cron jobs和Windows scheduled tasks的推荐模式是使用AlarmManager。当与IntentService结合使用时,这种方式可以很好地工作,因为服务将在后台线程上执行其工作,并在没有更多工作可做时关闭。但存在一个小问题:IntentService没有任何方法来保持设备的唤醒状态。如果闹钟是WAKEUP变体,则电话仅在处理闹钟的BroadcastReceiver处于其onReceive()方法时自行保持唤醒状态。否则,电话可能会重新进入睡眠状态。 WakefulIntentService通过结合IntentService的便捷性和部分WakeLock来尝试解决这个问题。


还不错,但是它不符合我的要求,它只是通过使用WakeLock来保持CPU的运行,就像我一样。问题是,当屏幕关闭且活动处于活跃状态时,我真的需要那个部分性的WakeLock来保持我的Handlers工作吗?在我的设备上,没有使用WakeLock也可以正常工作,但我不知道这是否适用于所有的Android手机,或者是否取决于设备的规格。如果是这样的话,我想知道是谁说过这个,或者在哪里的文档中提到了这一点,因为我找不到任何相关的内容。感谢您的回复,这对其他一些事情会很有帮助,CWAC有一些很酷的库。 - Jorge Fuentes González
作为一种替代方案,您尝试过AlarmManager.setInexactRepeating()吗?这是一种省电的重复闹钟,当闹钟响起时会发送一个Intent。http://developer.android.com/reference/android/app/AlarmManager.html - Patrick
一些处理程序每秒执行2/3次,因此我认为使用AlarmManager是一个不好的主意。我已经把所有东西都搞定了,而且工作得很好,也不会消耗太多电池,但如果我可以通过删除WakeLock来减少应用程序的电池消耗,那么我就会这样做。唯一和主要的问题是我是否真的需要使用WakeLock,因为在官方文档中我没有看到任何需要处理程序工作的地方,而且在我的手机上,应用程序在没有WakeLock的情况下完美地工作,但我不知道在其他设备上会怎样工作,因为我唯一能使用的Android设备就是我的 :-/ - Jorge Fuentes González
也许将来如果我用应用程序赚了一些钱,我会购买一些测试设备,但现在我还不能 :P - Jorge Fuentes González
我进一步调查了这个问题:当UI/Activity在后台运行时,你无法保证handler.postdelayed按预期工作(请参见编辑答案中的新链接)。这不是Android的工作方式,你必须设计你的应用程序,以便如果你收到任何更新并且你的应用程序在后台运行,你只需在你的活动回到前台时处理它,并省略你的后台更新。 - Patrick
1
至少!!!!!此外,在跟隨您發布的一些鏈接後,我找到了這個:https://groups.google.com/forum/?fromgroups#!topic/android-developers/Z_ngGZ1cTQk,這是一位Android工程師證實那個人說的...正是我想要的!真的,謝謝您!因此,我需要使用WakeLock來喚醒CPU,以防止其進入深度睡眠模式,也許我的設備沒有問題,因為它已經root並且具有Root Toolbox(我認為這是應用程序的名稱)調整了CPU。 - Jorge Fuentes González

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