安卓AlarmManager有时会延迟

4
我有一个应用程序,应该定期运行后台服务。我使用AlarmManager来实现这个行为。简而言之,它被设置为每分钟运行两次(每30秒一次),并且需要大约20秒来执行(大部分时间在休眠)。
我正在使用多个Android设备进行测试(带有4.1.2的Galaxy SII,带有4.2.2的Nexus 4,以及带有CyanogenMOD 10.1.2和4.2.2的后续设备,以及Nexus 7)。当连接到USB和调试器时,它们都表现得很一致。
一旦我拔掉设备并把它留在桌子上,我会注意到有时候服务会错过一个间隔。仔细查看日志,我发现服务有时会延迟一段时间。如果它应该在xx:05和xx:35运行,我会注意到它会在xx:45开始(比预期晚了10秒)。
服务做的第一件事是获取部分唤醒锁,以确保CPU在运行时不会进入睡眠状态-只有在完成所有工作之后才会释放此唤醒锁。
我的第一个想法是共享资源争用导致了这种行为(应用程序中有其他进程在运行),但服务甚至没有启动,直到大约10秒后才获取唤醒锁。
值得一提的是,在Nexus 4上,这种行为最为明显,达到了30%的数据丢失率,而在Galaxy SII和Nexus 7上则少得多(约2%),但由于这是无法解释的行为,因此仍然有问题。
1个回答

3
您没有说明使用的是什么类型的警报,但根据您的投诉,我假设它是一个_WAKEUP警报。如果是这样,我们唯一的保证是,如果我们使用广播PendingIntent,Android将在调用onReceive()期间保持设备保持清醒状态。如您所做的那样,使用服务PendingIntent是不可靠的,因为设备可能会在服务启动并获取WakeLock之前再次进入睡眠状态。
因此,更可靠的_WAKEUP警报模式是使用广播PendingIntent,让BroadcastReceiver acquire() WakeLock,然后让它调用startService()将控制权传递给您的服务。您的服务完成工作后,释放WakeLock
我将这个模式封装在我的WakefulIntentService组件中

谢谢您的回复。看起来,您所描述的概念显著提高了Nexus 4的可靠性,使其与Galaxy S2相当 - 但是仍然有一个“数据包”似乎丢失了(自从我做出更改以来,已经推送了500个数据包)。不幸的是,在该事件之后,日志被截断,因此我无法确定发生了什么。 - Iv4n
1
我将此答案标记为已接受,因为其中包含的信息提高了定时服务的可靠性。但仍存在0.2%的丢失率,我尚无法解释。 - Iv4n

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