Back in 2010, нам сказали, что единственная гарантия с AlarmManager
и _WAKEUP
-Style сигнализации в том, что если мы использовали радиопередачу PendingIntent
, затем Android будет держать устройство просыпаются достаточно долго для onReceive()
, чтобы закончить. У любого другого типа PendingIntent
такой гарантии не было.
Однако onReceive()
из BroadcastReceiver
вызывается в основной теме приложения, и мы не можем безопасно проводить там много времени. В идеале, это субмиллисекунда, поскольку, насколько вам известно, ваш пользовательский интерфейс сейчас находится на переднем плане, и вы не хотите, чтобы этот приемник вызывал jank.
Итак, рецепт стал:
- Есть тревога вызвать
BroadcastReceiver
- ли приемник приобретают
WakeLock
- Ресивер делегировать работу в
Service
, обычно представляет собой IntentService
- После завершения работ отпустите
WakeLock
.
My WakefulIntentService
была первой библиотекой, предлагающей поддержку этого рецепта. WakefulBroadcastReceiver
пришел позже. Они оба достигают той же цели, только с другой семантикой.
Обратите внимание, что «почему бы нам просто не приобрести WakeLock
в службе?» не работает, поскольку устройство может засыпать между концом onReceive()
и первым местом, где служба может получить возможность получить WakeLock
.
Теперь, для других ситуаций, не связанных с AlarmManager
, имея сервис управления собственным WakeLock
, вполне разумно. Фактически, это одна из причин, по которой я пошел со специальным IntentService
(WakefulIntentService
), а не специальным BroadcastReceiver
(WakefulBroadcastReceiver
).
Старая библиотека Google C2DM использовала ту же идею –