37 votes

Règles de connexion persistante des sockets Android

J'ai effectué quelques tests pour une solution personnalisée de notification push pour les appareils Android en utilisant des sockets persistants. J'aimerais partager mes découvertes et valider les résultats.

Description simple
L'application exécute un service en avant-plan, établit une connexion avec le serveur et maintient cette connexion grâce à des requêtes agressives (à un intervalle de 10 secondes). Si la connexion est détectée comme morte, l'application continue à essayer de se reconnecter indéfiniment. Le serveur envoie des notifications via un canal duplex.

Test 1 :

Pinging is done using a timer at 10 second intervals.
Server sends notification every minute.
Applications acquires wifi and wake locks.
Duration : 8 hours
Battery loss : ~14%

Test 2 :

Pinging is done using AlarmManager at 10 second intervals.
Server sends notification every minute.
Application acquires only a wifilock
Duration : 8 hours
Battery loss : ~7%

Hypothèses : Un paquet réseau entrant réveille automatiquement le CPU, donc pas besoin d'un wake lock. L'utilisation de AlarmManager pour le ping (au lieu de timers) signifie que nous n'avons pas besoin d'un wakelock.

Enlever ce wakelock a vraiment semblé aider la batterie. Étonnamment, le ping agressif de l'une ou l'autre solution n'a pas affecté la durée de vie de la batterie autant que je l'aurais pensé. (Nous avons effectué de nombreux autres tests, dont un où l'application maintenait simplement un wifilock et ne faisait rien, ce qui a entraîné une perte de batterie de 4 à 5 % sur la même période).

Comme l'application a pu envoyer avec succès toutes les requêtes ping et recevoir tous les messages entrants, je pense que mes hypothèses sont correctes. Mais j'aimerais avoir la confirmation d'un expert.

Une dernière question : Si l'application devait plutôt écouter les connexions entrantes. J'aurais besoin de maintenir un wakelock dans ce cas, correct ? Une connexion entrante ne réveille pas le CPU ? Nous ne suivons pas cette voie, mais nous voulions simplement confirmer.

De plus, veuillez ne pas recommander le GCM, il a été exclu par la politique de l'entreprise.

Merci.

13voto

Alex Points 779

Puisque cette question a suscité un certain intérêt et qu'il n'y a pas eu de confirmation, je vais simplement répondre maintenant. Cela fait un moment que les tests ont été effectués, et une solution de niveau production a été créée et rigoureusement testée. La suppression du verrouillage du réveil a quand même aidé la batterie et aucun autre problème n'a été trouvé comme des requêtes ping manquantes ou des notifications entrantes, c'est donc la seule validation que j'ai reçue sur lesdites hypothèses.

Autres choses à noter :

  • Dans la méthode OnReceive du BroadcastReceiver pour l'alarme ping, si vous n'appelez pas directement sur la socket (en créant un nouveau thread ou une intention), vous devrez maintenir un wake lock jusqu'à ce que la requête ping soit terminée. Android ne maintient un verrou de réveil que jusqu'au retour de OnReceive, après quoi il est possible (mais rare) que le CPU s'endorme avant la fin de la requête ping.

  • Utilisez un Serrure Wifi haute performance si les notifications sont sensibles.

  • Un autre problème spécifique à un appareil a affecté la solution, il est couvert par le document suivant aquí .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X