简体   繁体   English

Android AlarmManager有时会迟到

[英]Android AlarmManager sometimes late

I have an application that's supposed to run a background service at regular intervals and I'm using the AlarmManager to achieve this behavior. 我有一个应用程序,它应该定期运行后台服务,我正在使用AlarmManager来实现这种行为。 To cut a long story short, it's set up to run twice per minute (every 30 seconds) and it takes about 20 seconds to execute (mostly sleeping). 长话短说,它设置为每分钟运行两次(每30秒),执行大约需要20秒(大多数是睡觉)。

I am using several Android devices for testing (Galaxy SII with 4.1.2, Nexus 4 with 4.2.2 and later with CyanogenMOD 10.1.2 and Nexus 7 with 4.2.2) and all of them behave consistently while connected to USB and debugger. 我正在使用几个Android设备进行测试(带有4.1.2的Galaxy SII,带有4.2.2的Nexus 4和带有CyanogenMOD 10.1.2的Nexus 7和带有4.2.2的Nexus 7),所有这些设备在连接到USB和调试器时表现一致。

Once I unplug the device and leave it on the desk, I notice that SOMETIMES the service will miss one interval. 一旦我拔下设备并将其留在桌面上,我注意到有时服务将错过一个间隔。 Looking very closely at the log I see that the service is sometimes DELAYED by a certain period of time. 仔细查看日志,我发现该服务有时会在一段时间内延迟。 If it's supposed to run at xx:05 and xx:35 I'll notice it starting at xx:45 (10 seconds later than it should). 如果它应该在xx:05和xx:35运行,我会注意到它从xx:45开始(比它应该晚了10秒)。

The very first thing the service does is acquire the partial wake lock to ensure the CPU doesn't go to sleep while it's running - this wake lock isn't released until it's fully done with what it's supposed to do. 该服务所做的第一件事是获取部分唤醒锁定,以确保CPU在运行时不会进入休眠状态 - 这个唤醒锁定在它完全按照它应该做的事情完成之前不会被释放。

My first thought was that it was some share resource contention that was causing the behavior (there are other processes running with the app) but the service doesn't even start, it doesn't even acquire the wake lock until some 10 seconds later. 我的第一个想法是,导致行为的是一些共享资源争用(还有其他进程与应用程序一起运行)但是服务甚至没有启动,它甚至在10秒后才获得唤醒锁定。

It's worth mentioning this behavior is most pronounced on the Nexus 4 where up to 30% of the data is missing, while it's substantially less on the Galaxy SII and Nexus 7 (around ~2%) but it's still a concern since it's unexplained behavior. 值得一提的是,这种行为在Nexus 4上最为明显,其中高达30%的数据缺失,而Galaxy SII和Nexus 7的数据显着减少(约2%),但由于其无法解释的行为,它仍然是一个问题。

You did not state what sort of alarm that you are using, but given your complaints, I assume that it is a _WAKEUP alarm. 你没有说明你正在使用什么类型的警报,但鉴于你的抱怨,我认为这是一个_WAKEUP警报。 If so, the only guarantee we have is if we use a broadcast PendingIntent , Android will keep the device awake during the call to onReceive() . 如果是这样,我们唯一的保证是如果我们使用广播 PendingIntent ,Android将在调用onReceive()期间保持设备唤醒。 Using a service PendingIntent , as you are doing, is unreliable, as the device could fall back asleep before the service starts up and can acquire a WakeLock . 正如您所做的那样,使用服务 PendingIntent是不可靠的,因为设备可能会在服务启动之前重新入睡并且可以获取WakeLock

Hence, a more reliable pattern for a _WAKEUP alarm is to use a broadcast PendingIntent , have the BroadcastReceiver acquire() the WakeLock , then have it call startService() to pass control to your service. 因此, _WAKEUP警报的更可靠模式是使用广播PendingIntent ,让BroadcastReceiver acquire() WakeLock ,然后让它调用startService()将控制传递给您的服务。 Your service does its work, then releases the WakeLock . 您的服务完成其工作,然后发布WakeLock

I have this pattern wrapped up in my WakefulIntentService component . 我将这个模式包含在我的WakefulIntentService组件中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM