【问题标题】:Does AlarmManager require the PendingIntent to be of Type BroadcastReceiver?AlarmManager 是否要求 PendingIntent 为 BroadcastReceiver 类型?
【发布时间】:2014-09-15 16:08:33
【问题描述】:

AlarmManager 的文档似乎暗示(但没有完全明确要求)您传递给任何 set() 方法的 PendingIntent 应该是 BroadcastReceiver 类型,但我测试了传递其他组件类型(如IntentService),它似乎工作正常。

将非BroadcastReceiver Intent 与AlarmManager 一起使用是否安全?

【问题讨论】:

  • 根据您为PendingIntent 链接的文档,您可以看到它说您可以使用ActivityBroadcastReceiverService
  • 我看到了,但我在 PendingIntent 中看不到任何 AlarmManager 特定的措辞。我想知道AlarmManager 是否对我传入的PendingIntent 做正确的事情

标签: android broadcastreceiver alarmmanager android-pendingintent intentservice


【解决方案1】:

是的,它一直有效,但我怀疑不是你想的那样。您可以将任何 PendingIntent 与警报一起使用;这确实可能是一项活动或服务 PendingIntent。如果它是 PendingIntent 服务,则操作系统会在警报触发时为您调用 startService()。隐藏的问题是关于 wakeup 警报的行为。

当任何警报触发时,只要发送 PendingIntent 所需的时间,操作系统就会代表发送者持有一个唤醒锁,此时唤醒锁被释放,并且允许设备重新进入睡眠状态。 “只要它需要交付”的确切含义取决于所使用的 PendingIntent 类型。

广播传输本质上被视为同步:唤醒锁由警报管理器持有,直到接收者的 onReceive() 回调返回。这为您提供了一个硬性保证,即您想要在 onReceive() 中执行的任何处理都可以保证在设备不休眠的情况下继续进行。

但是,活动和服务 PendingIntent 交付不会以相同的方式等待接收者。使用这些类型的警报 PendingIntents,设备保持清醒的时间足以开始启动目标活动或服务的过程,但它可以(并且确实)在启动开始后立即返回睡眠状态,在目标代码真正有机会运行之前。在实践中,这意味着使用服务 PendingIntent,即使警报是唤醒警报,服务通常也不会真正执行,直到整个设备被正常唤醒,例如下次用户手动打开屏幕时。

有时这没关系,如果您的代码实际上并不关心即使闹钟在凌晨 3 点响起,服务直到早上 7 点才开始运行,此时闹钟响起并长时间点亮手机。然而,更多时候,应用需要做的是使用广播警报,然后在它们的 onReceive() 中——知道设备一返回就会休眠——获取它们的自己的唤醒锁并启动启动该唤醒锁下的服务等。

有一个很棒的支持库类WakefulBroadcastReceiver,它封装了这个alarm-wakelock-service舞蹈,使它既简单又防弹;它是https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html。如果您想启动服务以响应唤醒警报,请使用它。

【讨论】:

  • 设备唤醒时是否会处理意图?
  • 是的。这与某些应用程序在设备进入睡眠状态时调用 startService() 或 startActivity() 完全相同。这不会中止操作;直到有东西再次唤醒设备,它才开始处理开始。
  • 谢谢 - 我找不到任何关于此的文档 - 我非常感谢一个链接 ;) - 你可能想回答这个问题:stackoverflow.com/questions/31086067/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多