2016-11-21 13 views
0

У меня есть IntentService, который вызывается из другого места (скажем, из компонента X) в моем приложении. Я хочу, чтобы его onHandleIntent работал с блокировкой слежения. Кажется, есть два способа сделать это:Нужна блокировка следа в IntentService: зачем проходить через WakefulBroadcastReceiver?

  1. Приобретение и освобождение замка следа в onHandleIntent.
  2. Создать новый WakefulBroadcastReceiver, начинающий эту услугу. В компоненте X вызовите этот приемник вместо службы напрямую.

Второй вариант, как представляется, recommended. Но почему? Имеет ли добавленное косвенное и шаблонное предложение какое-либо преимущество перед первым подходом?

ответ

2

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).

+0

Старая библиотека Google C2DM использовала ту же идею –