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

And*_*ynn 3 android broadcastreceiver alarmmanager intentservice android-pendingintent

AlarmManager的文档似乎暗示(但并不直接明确要求)您传入任何方法的PendingIntentset()应该是BroadcastReceiver类型,但我测试了传入其他组件类型(如IntentService),它似乎工作得很好.

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

cta*_*ate 8

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

当任何警报触发时,操作系统会代表发送者持有唤醒锁,只要它能够传递PendingIntent,此时释放唤醒锁并允许设备返回睡眠状态."只要需要交付"的确切含义取决于使用哪种PendingIntent.

广播传送基本上被视为同步:唤醒管理器保持唤醒锁,直到收件人的onReceive()回调返回.这使您很难保证在onReceive()中要执行的任何处理都可以保证在没有设备休眠的情况下继续进行.

但是,活动和服务PendingIntent传递不会以相同的方式等待收件人.对于那些类型的警报PendingIntents,设备保持清醒足够长的时间以开始启动目标活动或服务的过程,但是在目标代码实际具有之前它可以(并且确实)在启动开始之后立即返回睡眠状态.有机会跑.实际上,这意味着对于服务PendingIntent,即使警报是唤醒警报,服务通常也不会实际执行,直到整个设备正常唤醒,例如下次用户手动打开屏幕.

有时这是可以的,如果您的代码实际上并不关心,即使闹钟在凌晨3点开始,该服务也没有开始运行,直到闹钟响起并在长时间点亮手机上午7点.但更常见的是,应用程序需要做的是使用广播警报,然后在他们的onReceive()中 - 知道设备一返回就会睡觉 - 获取自己唤醒锁并在该唤醒锁下启动服务,等等

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