简体   繁体   English

AlarmManager是否要求PendingIntent属于BroadcastReceiver类型?

[英]Does AlarmManager require the PendingIntent to be of Type BroadcastReceiver?

The documentation for AlarmManager seems to imply (but does not outright explicitly require) that the PendingIntent you pass in to any of the set() methods should be of the type BroadcastReceiver , but I tested passing in other component types (like an IntentService ) and it seemed to work fine. AlarmManager的文档似乎暗示(但并不直接明确要求)您传入任何set()方法的PendingIntent应该是BroadcastReceiver类型,但我测试了传入其他组件类型(如IntentService )和它似乎工作正常。

Is it safe to use non- BroadcastReceiver Intents with AlarmManager ? 将非BroadcastReceiver Intents与AlarmManager一起使用是否安全?

Yes, and it has always worked, but I suspect not in the way that you're thinking. 是的,它一直有效,但我怀疑不是你想的那样。 You can use any PendingIntent with an alarm; 您可以将任何PendingIntent与警报一起使用; this could indeed be an activity or service PendingIntent. 这可能确实是一项活动或服务PendingIntent。 If it's a service PendingIntent, then the OS will call startService() for you when the alarm fires. 如果它是服务PendingIntent,那么操作系统将在警报触发时为您调用startService()。 The hidden catch is about the behavior of wakeup alarms. 隐藏的捕获是关于唤醒警报的行为。

When any alarm fires, the OS holds a wakelock on the sender's behalf for as long as it takes to deliver the PendingIntent, at which point the wakelock is released and the device is allowed to go back to sleep. 当任何警报触发时,操作系统会代表发送者持有唤醒锁,只要它能够传递PendingIntent,此时释放唤醒锁并允许设备返回睡眠状态。 The exact meaning of "as long as it takes to deliver" depends on which kind of PendingIntent is being used. “只要需要交付”的确切含义取决于使用哪种PendingIntent。

Broadcast delivery is essentially treated as synchronous: the wakelock is held by the Alarm Manager until the recipient's onReceive() callback returns. 广播传送基本上被视为同步:唤醒管理器保持唤醒锁,直到收件人的onReceive()回调返回。 This gives you a hard guarantee that whatever processing you want to do in onReceive() is guaranteed to proceed without the device sleeping. 这使您很难保证在onReceive()中要执行的任何处理都可以保证在没有设备休眠的情况下继续进行。

However, activity and service PendingIntent delivery does not wait for the recipient in the same way. 但是,活动和服务PendingIntent传递不会以相同的方式等待收件人。 With those kinds of alarm PendingIntents, the device remains awake long enough to begin the process of starting the target activity or service, but then it can (and does) go back to sleep immediately after that launch has begun, before the target code actually has a chance to run. 对于那些类型的警报PendingIntents,设备保持清醒足够长的时间以开始启动目标活动或服务的过程,但是在目标代码实际具有之前它可以(并且确实)在启动开始之后立即返回睡眠状态。有机会跑。 In practice this means that with a service PendingIntent, even if the alarm is a wakeup alarm, the service will often not actually execute until the device as a whole is woken up normally, eg the next time the user turns on the screen manually. 实际上,这意味着使用服务PendingIntent,即使警报是唤醒警报,服务通常也不会实际执行,直到整个设备正常唤醒,例如下次用户手动打开屏幕。

Sometimes this is okay, if your code doesn't actually care that even though the alarm fired at 3am, the service didn't start running until 7am when the alarm clock went off and lit up the phone for an extended period. 有时这是可以的,如果您的代码实际上并不关心,即使闹钟在凌晨3点开始,该服务也没有开始运行,直到闹钟响起并在长时间点亮手机上午7点。 More often, though, what apps need to do is use a broadcast alarm, then in their onReceive() -- knowing that the device will sleep as soon as they return -- acquire their own wakelock and start up the service under that wakelock, etc. 但更常见的是,应用程序需要做的是使用广播警报,然后在他们的onReceive()中 - 知道设备一返回就会睡觉 - 获取自己唤醒锁并在该唤醒锁下启动服务,等等

There is a terrific support library class called WakefulBroadcastReceiver that encapsulates this alarm-wakelock-service dance and makes it both easy and bulletproof; 有一个非常好的支持库类WakefulBroadcastReceiver,它封装了这个警报唤醒服务舞蹈,使它既简单又防弹; it's https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html . 这是https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html Use that if you ever want to start a service in response to a wakeup alarm. 如果您想要启动服务以响应唤醒警报,请使用它。

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

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