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%),但它仍然是一个问题,因为它是无法解释的行为。

4

1 回答 1

3

您没有说明您使用的是哪种警报,但鉴于您的投诉,我认为这是_WAKEUP警报。如果是这样,我们唯一的保证是如果我们使用广播 PendingIntent,Android 将在调用onReceive(). 正如您所做的那样,使用服务 PendingIntent是不可靠的,因为设备可能会在服务启动之前重新进入睡眠状态并且可以获取WakeLock.

因此,更可靠的_WAKEUP警报模式是使用广播PendingIntent,拥有BroadcastReceiver acquire()WakeLock然后调用它startService()以将控制权传递给您的服务。您的服务完成其工作,然后发布WakeLock.

我将这种模式包装在我的WakefulIntentService组件中。

于 2013-07-19T12:17:05.157 回答