Android: garder un service d'arrière-plan en vie (prévention des processus de la mort)
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/
Vous devez vous connecter pour publier un commentaire.
Pour Android 2.0 ou version ultérieure, vous pouvez utiliser le
startForeground()
méthode à votre Service dans le premier plan.La la documentation indique les éléments suivants:
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.startForeground()
pour tuer si le service serait perturbant pour l'utilisateur - par exemple, de faire quelque chose comme jouer de la musique. Ceci étant le cas, il devrait être quelque chose que l'utilisateur est conscient et a donc de la visibilité par l'intermédiaire d'une Notification.startForeground()
n'est pas destiné à être une alternative pour répondre à des événements de cycle de vie de manière appropriée.onForground
. Comment puis-je le faire? stackoverflow.com/questions/35168209/...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.
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). Sur la base des 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?1Android fournit collant services 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.
Image que vous voulez écrire un client XMPP pour Android. Si vous demandez de la priorité de premier plan pour la
Service
qui contient votre XMPP connexion? Certainement pas, il n'y a absolument aucune raison de le faire. Mais vous voulez utiliserSTART_STICKY
comme indicateur de retour pour votre serviceonStartCommand
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.
START_STICKY
n'est pas destiné à cet usage, mais à garantir que, dans un temps limité tâche est conclu à l'issue d'un processus tuer. Si, pour une raison quelconque, le service n'est pas "coller" (par exemple, est incapable de se reconnecter au serveur XMPP), le système peut décider, il a essayé de suffisamment de temps et d'arrêter tout simplement de redémarrer le service, pour ne pas mentionner ce serait d'exiger le service a continué de tourner dans une boucle tant que la connexion est en place qui ne peuvent simplement pas être fait. Cela dit, je ne peux pas trouver une solution pour garder/reprise de la connexion entre les processus tue (autres que la planification périodique de tentatives de reconnexion viaAlarmManager
).START_STICKY
est exactement ce que vous voulez l'utiliser ici. "...essayé assez de temps et d'arrêter tout simplement de redémarrer le service,..." Non, le système Android n'est pas au courant de XMPP connexion (re)tente un collant Android service effectue. Il voit juste le service en cours d'exécution et maintient en cours d'exécution. C'est le contrat de l'API Android prévoit que si un service est démarré collante. "...mentionner ce serait d'exiger le service a continué de tourner dans une boucle...", Oui, c'est exactement pourquoi la plupart des Android les Services ont un Looper (ce qui est généralement rendue abstraite de l'utilisateur à l'aide d'un Android).Service.onStartCommand()
ouIntentService.onHandleIntent()
méthode au lieu de cela, ce qui n'est pas viable.while
boucle, le service sera terminé dès queonStartCommand()
ouonHandleIntent()
complète (si il y a pas d'autres intentions dans la file d'attente) et la connexion va s'en aller (à moins que la référence à la connexion en elle-même est tenu par une autre classe). De toute façon le service est plus et ne sera pas redémarré après l'application du processus est tué.stopSelf()
méthode a jamais besoin de... s'avère que les zones répétées à la marche au ralenti des services sont plutôt bon marché pour le système à maintenir autour de si les services ne sont pas arrêtés, je n'ai pas dit qu'elles doivent être conçues de cette manière. Merci pour les précisions!stopSelf()
est très pratique si vous voulez être gentil avec le système et la libération de la ressource acquise par votre service quand vous savez que vous n'aurez pas besoin de lui (ou dans un futur proche). Mais n'oubliez pas que même si vous n'utilisez passtopSelf()
Android finira par cesser de votre service, et si son redémarrage dépend si le service est collant ou pas.J'ai eu un problème similaire. Sur certains appareils, après un certain temps, Android tue mon service et même startForeground() n'aide pas. Et mon client n'aime pas ce problème. Ma solution est d'utiliser AlarmManager classe pour vous assurer que le service est en cours d'exécution lorsque c'est nécessaire. J'utilise AlarmManager de créer une sorte de minuterie chien de garde. Il vérifie de temps en temps si le service doit être en cours d'exécution et le redémarrer.
Aussi j'utilise SharedPreferences de garder le drapeau si le service doit être en cours d'exécution.
Création/rejetant mon minuteur:
De réception et de traitement de l'intention de l'horloge de surveillance:
En effet, j'utilise WakefulBroadcastReceiver au lieu de BroadcastReceiver. Je vous ai donné le code avec BroadcastReceiver juste pour simplifier.
http://developer.android.com/reference/android/content/Context.html#BIND_ABOVE_CLIENT
public static final int BIND_ABOVE_CLIENT -- Ajouté dans API de niveau 14
Drapeau pour
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.Autres drapeaux du 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
anciennes applications qui ne spécifient pas
BIND_AUTO_CREATE
automatiquement les drapeauxBIND_WAIVE_PRIORITY
etBIND_ADJUST_WITH_ACTIVITY
jeu pour eux.Garder votre service une faible empreinte, ce qui réduit la probabilité de Android la fermeture de votre application. Vous ne pouvez pas l'empêcher d'être tué parce que si vous pouviez alors les gens pourraient facilement créer persistante des logiciels espions
onForground
. Comment puis-je le faire? stackoverflow.com/questions/35168209/...Je suis en train de travailler sur une application et le visage de question de tuer mon service par sur l'app tuer. J'ai fait des recherches sur google et trouvé que j'ai à faire au premier plan. voici le code:
houblon qu'il peut aide!!!!