51 votes

Android: maintenir en vie un service d'arrière-plan (prévenir la mort du processus)

J'ai un service qui est défini comme:

public class SleepAccelerometerService extends Service implements SensorEventListener

Essentiellement, je fais une application qui surveille l'accéléromètre de l'activité pour diverses raisons, alors que l'utilisateur dort avec son téléphone sur le lit. C'est un long-exécution d'un service qui ne DOIT PAS être tué au cours de la nuit. En fonction du nombre d'arrière-plan des applications et des processus périodiques se produire au cours de la nuit, android tue parfois hors de mon processus, mettant ainsi fin à mon service. Exemple:

10-04 03:27:41.673: INFO/ActivityManager(1269): Process com.androsz.electricsleep (pid 16223) has died.
10-04 03:27:41.681: INFO/WindowManager(1269): WIN DEATH: Window{45509f98 com.androsz.electricsleep/com.androsz.electricsleep.ui.SleepActivity paused=false}

Je ne veux pas forcer l'utilisateur à avoir "SleepActivity" ou une autre activité dans mon application le premier plan. Je ne peux pas avoir mon service s'exécute périodiquement, car il est constamment l'interception onSensorChanged.

Des conseils à donner? le code source est ici: http://code.google.com/p/electricsleep/

72voto

Dave Webb Points 90034

Pour Android 2.0 ou version ultérieure, vous pouvez utiliser l' startForeground() méthode pour démarrer votre Service dans le premier plan.

La documentation indique les éléments suivants:

Un service démarré pouvez utiliser l' startForeground(int, Notification) API pour mettre le service au premier plan de l'état, où le système considère qu'il est quelque chose que l'utilisateur est activement à la connaissance et donc pas un candidat pour le meurtre de lors de manque de mémoire. (Il est toujours théoriquement possible pour que le service soit tué dans des conditions extrêmes de pression de mémoire à partir de l'actuel premier plan de l'application, mais dans la pratique, cela ne devrait pas être une préoccupation.)

L'est principalement prévu pour quand tuer le service serait perturbant pour l'utilisateur, par exemple, le meurtre d'un lecteur de musique service de cesser de jouer de la musique.

Vous aurez besoin de fournir un Notification à la méthode qui est affiché dans la Barre de Notifications dans la section en Cours.

16voto

Witold Graca Points 176

Lorsque vous liez votre Service pour l'Activité avec BIND_AUTO_CREATE votre service est tué juste après votre Activité est Détruite et indépendant. Il ne dépend pas de la façon dont vous avez mis en œuvre de vos Services unBind méthode, il sera tué.

L'autre façon de faire est à votre Service avec startService méthode de votre Activité. De cette façon, même si votre Activité est détruit votre service ne sera pas détruit ou même en pause, mais vous devez mettre en pause/détruire par vous-même avec stopSelf/stopService le cas échéant.

11voto

Flow Points 8018

Comme Dave l'a déjà souligné, vous pouvez exécuter votre Service avec la priorité de premier plan. Mais cette pratique doit être utilisée uniquement lorsque c'est absolument nécessaire, c'est à dire quand il serait la cause d'une mauvaise expérience utilisateur si le Service a été tué par Android. C'est ce que le "premier plan" signifie vraiment: Votre application est en quelque sorte dans le premier plan et l'utilisateur ne remarque immédiatement s'il est tué (par exemple parce qu'il a joué un morceau ou d'une vidéo).

Dans la plupart des cas, de demander la priorité de premier plan pour votre Service est contraproductive!

Pourquoi est-ce? Quand Android décide de tuer un Service, il le fait parce qu'il est à court de ressources (généralement de RAM). De Base sur les différentes classes de priorité, Android décide de processus en cours d'exécution, et ce inclus les services, de mettre fin afin de libérer des ressources. C'est un processus sain et que vous souhaitez produire de sorte que l'utilisateur dispose d'une expérience agréable. Si vous demandez la priorité de premier plan, sans une bonne raison, juste pour garder votre service d'être tué, il sera plus susceptible de causer une mauvaise expérience utilisateur. Ou pouvez-vous garantir que votre service reste dans un minimum la consommation de ressources et n'a pas de fuites de mémoire?1

Android fournit des services attractifs pour marquer les services qui devraient être redémarré après un certain délai de grâce, s'ils avaient été tués. Ce redémarrage se produit habituellement dans un délai de quelques secondes.

L'Image que vous voulez écrire un client XMPP pour Android. Si vous demandez de la priorité de premier plan pour l' Service qui contient votre XMPP connexion? Certainement pas, il n'y a absolument aucune raison de le faire. Mais vous voulez utiliser START_STICKY comme indicateur de retour pour votre service de l' onStartCommand méthode. Afin que votre service est arrêté quand il y a pression sur les ressources et redémarré une fois que la situation est revenue à la normale.

1: je suis sûr que beaucoup d'applications Android ont des fuites de mémoire. Ce quelque chose que les occasionnels (bureau) programmeur n'a pas beaucoup.

4voto

http://developer.android.com/reference/android/content/Context.html#BIND_ABOVE_CLIENT

public static final int BIND_ABOVE_CLIENT -- Ajout de l'API de niveau 14

Drapeau de l' bindService(Intent, ServiceConnection, int): indique que le client demande la liaison à ce service estime que le service soit plus important que l'application elle-même. Lorsqu'il est défini, la plate-forme va essayer d'avoir la mémoire de tueur de tuer l'application avant de tuer le service, il est lié à l', si ce n'est pas garanti d'être le cas.

D'autres indicateurs d'un même groupe sont: BIND_ADJUST_WITH_ACTIVITY, BIND_AUTO_CREATE, BIND_IMPORTANT, BIND_NOT_FOREGROUND, BIND_WAIVE_PRIORITY.

À noter que le sens de BIND_AUTO_CREATE a changé dans ICS, et les anciennes applications qui ne sont pas en mesure de spécifier BIND_AUTO_CREATE automatiquement les drapeaux BIND_WAIVE_PRIORITY et BIND_ADJUST_WITH_ACTIVITY jeu pour eux.

2voto

BeRecursive Points 4334

Conservez une empreinte de service réduite, cela réduira la probabilité qu'Android ferme votre application. Vous ne pouvez pas empêcher sa mort, car si vous le pouviez, les gens pourraient facilement créer des logiciels espions persistants.

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