2016-11-21 1 views
0

J'ai un IntentService qui est appelé d'ailleurs (disons du composant X) dans mon application. Je veux que son onHandleIntent fonctionne avec un verrou de sillage. Il semble y avoir deux façons de le faire:Besoin d'un verrou de réveil dans IntentService: pourquoi passer par WakefulBroadcastReceiver?

  1. Acquérir et libérer un verrou de sillage dans onHandleIntent. Créez un nouveau WakefulBroadcastReceiver qui démarre ce service. Dans le composant X, appelez directement ce récepteur au lieu du service.

La deuxième option semble être recommended. Mais pourquoi? Est-ce que l'indirection ajoutée et la règle standard offrent un avantage par rapport à la première approche?

Répondre

2

Back in 2010, on nous a dit que la seule garantie avec AlarmManager et _WAKEUP alarmes -style était que si nous avons utilisé une émission PendingIntent, alors Android garderait l'appareil assez éveillé longtemps pour onReceive() pour terminer. Tout autre type de PendingIntent n'avait pas ce genre de garantie.

Cependant, onReceive() d'un BroadcastReceiver est appelée sur le thread d'application principale, et nous ne pouvons pas y passer beaucoup de temps en toute sécurité. Idéalement, il s'agit d'une sous-milliseconde, comme pour tout ce que vous savez, votre interface utilisateur se trouve au premier plan en ce moment, et vous ne voulez pas que ce récepteur cause le problème.

Ainsi, la recette est devenue:

  • Demandez l'alarme déclenche un BroadcastReceiver
  • le récepteur pour acquérir une WakeLock
  • Demandez au délégué du récepteur le travail à un Service, généralement un IntentService
  • Demander au service de publier le WakeLock lorsque le travail est terminé

My WakefulIntentService était la première bibliothèque à offrir un support pour cette recette. WakefulBroadcastReceiver est arrivé plus tard. Ils accomplissent tous les deux la même fin, juste avec des sémantiques différentes.

Notez que "pourquoi ne pas simplement acquérir un WakeLock dans le service?" échoue parce que l'appareil pourrait s'endormir entre la fin de onReceive() et le premier endroit où le service pourrait avoir une chance d'acquérir le WakeLock.

Maintenant, pour d'autres situations, n'impliquant pas AlarmManager, avoir le service gérer son propre WakeLock est parfaitement raisonnable. En fait, c'est l'une des raisons pour lesquelles je suis allé avec un IntentService (WakefulIntentService) spécial plutôt qu'un BroadcastReceiver spécial (WakefulBroadcastReceiver).

+0

L'ancienne bibliothèque Google C2DM a utilisé la même idée –