Comment vérifier si un service est en cours d'exécution sur Android?
Comment puis-je vérifier si un service d'arrière-plan est en cours d'exécution?
Je veux un Android activité qui permet de basculer l'état du service -- il me permet de l'allumer si elle est éteinte et que si on est sur.
- Découvrez ce guide allemand.
- la bonne réponse est ci-dessous et non pas l'une portant la mention: stackoverflow.com/a/5921190/2369122
- Si cela n'a pas déjà été nerfed comme
getRunningTasks()
, il sera probablement. - à l'aide de la getSystemService() fonction que vous pouvez récupérer tous les services en cours d'exécution. boucle à travers le et vérifiez que le service de votre existe pas dans la liste vous pouvez voir ici un petit échantillon wiki.workassis.com/android-check-the-service-is-running
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même problème il n'ya pas longtemps. Depuis mon service à l'échelon local, j'ai fini par tout simplement à l'aide d'un champ statique dans la classe de service pour basculer de l'état, comme décrit par hackbod ici
MODIFIER (pour l'enregistrement):
Voici la solution proposée par hackbod:
onDestroy()
n'est pas appelé. Si la variable statique ne peut pas être mis à jour dans un tel scénario entraînant des comportements incohérents.J'utilise la suite de l'intérieur d'une activité:
Et je l'appelle à l'aide:
Cela fonctionne de manière fiable, car il est basé sur les informations sur l'exécution des services fournis par le système d'exploitation Android à travers ActivityManager#getRunningServices.
Toutes les approches à l'aide de onDestroy ou onSometing des événements ou des Liants ou des variables statiques ne fonctionnera pas de manière fiable, car en tant que développeur, vous ne savez jamais, quand Android décide de tuer votre processus ou des rappels sont appelés ou non. Veuillez noter que le "tuables" colonne de la événements du cycle de vie de la table dans l'Android documentation.
bindService
avec0
comme drapeau ne pas démarrer le service, mais cette méthode n'identifie comme en cours d'exécution.ActivityManager cannot be resolved to a type
Service
est en cours d'exécution, afin de ne pas démarrer à nouveau et de nouveau. Il est également utile dans le cas, si un utilisateur aForce Stop
votre application intentionnellement/involontairement!return service.started;
améliorereturn true;
?<? extends Service>
de sorte qu'il est plus difficile de l'appeler avec le mauvais argument?getRunningServices
est obsolète. Cette réponse nécessite une mise à jour pour une version plus récente.getRunningServices
n'est plus disponible pour troisième partie applications. Pour la compatibilité ascendante, il sera toujours retourner à l'appelant de ses propres services.Obtenu!
Vous DOIT appel
startService()
pour votre service, pour être correctement enregistré et en passantBIND_AUTO_CREATE
ne suffira pas.Et maintenant le ServiceTools classe:
Un petit complément est:
Mon but est de savoir si un service est en cours d'exécution sans réellement l'exécution si elle n'est pas en cours d'exécution.
Appel bindService ou l'appel d'une intention qui peut être pris par le service n'est pas une bonne idée alors qu'il va commencer le service s'il n'est pas en cours d'exécution.
Donc, comme miracle2k suggéré, le mieux est d'avoir un champ statique dans la classe de service pour savoir si le service a été commencé ou pas.
Pour le rendre encore plus propre, je vous suggère de transformer le service dans un singleton avec un très très chargement différé: c'est, il n'y a pas d'instanciation à tous les singleton exemple par le biais de méthodes statiques. La statique de la méthode getInstance de votre service/singleton retourne l'instance du singleton si elle a été créée. Mais il n'a pas réellement démarrer ou instancier le singleton lui-même. Le service est démarré uniquement par le biais de la normale de démarrage du service méthodes.
Il serait alors encore plus propre à modifier le modèle de conception singleton pour renommer la confusion de la méthode getInstance en quelque chose qui ressemble
isInstanceCreated() : boolean
méthode.Le code ressemblera à:
Cette solution est élégante, mais elle n'est pertinente que si vous avez accès à la classe de service et uniquement pour les classes de iside l'application/paquet du service. Si vos classes sont en dehors de l'application de service/paquet alors vous pouvez interroger l'ActivityManager avec des limitations souligné par Pieter-Jan Van Robays.
Vous pouvez l'utiliser (je n'ai pas essayé encore, mais j'espère que cela fonctionne):
De la startService méthode retourne un Nomcomposant objet si il est déjà en cours d'exécution du service. Si non, null sera retourné.
Voir résumé public Nomcomposant startService (Intent service).
Ce n'est pas comme la vérification de je pense, parce que c'est le lancement du service, de sorte que vous pouvez ajouter
stopService(someIntent);
en vertu du code.if(startService(someIntent) != null)
qui permettra de vérifier queIsserviceRunning
mais qui va également jouer à un nouveau service.J'ai légèrement modifié l'une des solutions présentées ci-dessus, mais le passage de la classe au lieu d'une chaîne générique nom, afin d'être sûr de comparer des chaînes de caractères qui sortent de la même méthode
class.getName()
et puis
Class<? extends Service>
Un extrait de Android docs:
Pense de ce hack "pinging" la
Service
puisque l'on peut diffuser de manière synchrone l'on peut diffuser et d'obtenir un résultat -- de façon synchrone -- sur le thread d'INTERFACE utilisateur.Service
Activity
Je veux juste ajouter une note de la réponse par @Snicolas. Les étapes suivantes peuvent être utilisées pour arrêter le service avec/sans appel
onDestroy()
.onDestroy()
disant: Allez dans Paramètres -> Application -> Services en cours d'Exécution -> Sélectionner et d'arrêter votre service.onDestroy()
pas Appelé: Allez dans Paramètres -> Application -> Gérer les Applications -> Sélectionner et de "Forcer l'Arrêt" de votre application dans laquelle le service est exécuté. Cependant, en tant que votre demande est arrêté ici, pour que les instances du service sera également arrêté.Enfin, je tiens à mentionner que l'approche parlé il y a utilisation d'une variable statique dans la classe singleton est de travailler pour moi.
onDestroy
n'est pas toujours appelé dans le service, de sorte que c'est inutile!Par exemple: il suffit de lancer l'application avec un seul changement à partir d'Eclipse. L'application est violemment sorti de l'aide de SIG: 9.
La bonne façon de vérifier si un service est en cours d'exécution est tout simplement de lui demander. Mettre en œuvre un BroadcastReceiver à votre service qui répond aux pings de vos activités. Enregistrer le BroadcastReceiver lorsque le service démarre, et il désinscription lorsque le service est détruit. À partir de votre activité (ou de tout composant), envoyer un diffusion locale à l'intention du service et s'il répond, vous savez qu'il est en cours d'exécution. Notez la différence subtile entre ACTION_PING et ACTION_PONG dans le code ci-dessous.
Tout d'abord il ne faut pas tenter de joindre le service à l'aide de la ActivityManager. (Discuté ici)
Services peut s'exécuter sur leur propre, être lié à une Activité ou les deux. Le moyen de vérifier, dans une Activité, si votre Service est en cours d'exécution ou non est de faire une interface (qui s'étend de Liant) où vous déclarer des méthodes à la fois, l'Activité et le Service, de comprendre. Vous pouvez le faire en faisant votre propre Interface où vous déclarez par exemple "isServiceRunning()".
Vous pouvez ensuite lier votre Activité à votre Service, exécutez la méthode isServiceRunning(), le Service permettra de vérifier lui-même si elle fonctionne ou pas et retourne un booléen à votre Activité.
Vous pouvez également utiliser cette méthode pour arrêter de votre Service ou d'interagir avec lui d'une autre manière.
J'ai utilisé ce tutoriel pour savoir comment mettre en Œuvre ce scénario dans ma demande.
Xamarin C# version:
GetSystemService
.Pour les cas d'utilisation donné, là, on peut simplement utiliser la
stopService()
de retour de la méthode de la valeur. Il retournetrue
si il existe le service spécifié et il est tué. Sinon, il retournefalse
. Donc, vous pouvez redémarrer le service si le résultat estfalse
d'autre, il est assuré que le service a été arrêté. 🙂 Il serait mieux si vous avez un coup d'oeil à cette.De nouveau, une autre alternative que les gens peuvent trouver plus propre si ils utilisent en attendant les intentions (par exemple avec la
AlarmManager
:Où
CODE
est une constante que vous définissez en privé dans votre classe pour identifier l'instance d'intentions associées à votre service.Ci-dessous est un élégant hack qui couvre tous les
Ifs
. C'est pour les services locaux seulement.Et puis, plus tard:
L'appel
ActivityManager.getRunningServices
est obsolète depuis Android OIl peut y avoir plusieurs services avec le même nom de classe.
Je viens de créer deux applications. Le nom du package de la première application est
com.example.mock
. J'ai créé un sous-paquetage appelélorem
dans l'application et un service appeléMock2Service
. Donc, son nom complet estcom.example.mock.lorem.Mock2Service
.Puis j'ai créé la deuxième application et un service appelé
Mock2Service
. Le nom du package de la seconde application estcom.example.mock.lorem
. Le nom pleinement qualifié du service estcom.example.mock.lorem.Mock2Service
, trop.Voici mon logcat de sortie.
Une meilleure idée est de comparer
ComponentName
cas carequals()
deComponentName
compare les deux noms de paquets et les noms de classe. Et il ne peut y avoir deux applications avec le même nom du package installé sur un périphérique.La méthode equals() de
ComponentName
.Nomcomposant
Cela s'applique de plus en plus vers l'Intention du Service de débogage, car ils frayer un thread, mais ils peuvent travailler pour les services réguliers ainsi. J'ai trouvé ce fil grâce à Binging
Dans mon cas, j'ai joué un peu avec le débogueur et trouvé le fil de la vue. Il sorte de ressemble à l'puce icône dans MS Word. De toute façon, vous n'avez pas à être en mode débogage pour l'utiliser. Cliquez sur le processus et cliquez sur ce bouton. L'Intention des Services apparaîtront alors qu'ils sont en cours d'exécution, au moins sur l'émulateur.
Si le service appartient à un autre processus ou APK utiliser la solution basée sur le ActivityManager.
Si vous avez accès à sa source, il suffit d'utiliser la solution basée sur un champ statique. Mais au lieu d'utiliser un booléen, je voudrais suggérer à l'aide d'un objet Date. Alors que le service est en cours d'exécution, juste de mettre à jour sa valeur à "maintenant" et quand il finit de le régler à la valeur null. De l'activité, vous pouvez vérifier si sa valeur null ou la date est trop vieux, ce qui signifie qu'il n'est pas en cours d'exécution.
Vous pouvez également envoyer de diffusion de notification de votre service indiquant qui est en cours d'exécution le long de plus d'informations, comme des progrès.
À l'intérieur de TheServiceClass définir:
Puis Dans onStartCommand(...)
Ensuite, appelez
if(TheServiceClass.serviceRunning == true)
de toute la classe.stopService
. Au moins pour Intention de services.onDestroy()
sera appelée immédiatement, maisonHandleIntent()
va encore être en cours d'exécutionsimple d'utilisation lier avec de ne pas créer d'auto- voir ps. et mise à jour...exemple :
pourquoi ne pas l'utiliser? getRunningServices()
Remarque: cette méthode est uniquement destiné à des fins de débogage ou de la mise en œuvre de la gestion des services de type interfaces utilisateur.
ps. android documentation est trompeur, j'ai ouvert un sujet sur google tracker pour éliminer tous les doutes:
https://issuetracker.google.com/issues/68908332
comme nous pouvons le voir se lier service appelle en fait une transaction via ActivityManager classeur à travers le Service de cache liants - je la force de la piste de laquelle le service est responsable de la liaison, mais comme nous pouvons voir le résultat de bind est:
transaction est effectuée par le classeur:
suivante:
il est en ActivityThread via:
ce qui est appelé en ActivityManagerService dans la méthode:
alors:
mais il n'y a pas de "activité" seule fenêtre de paquet et d'alarme..
donc nous avons besoin de revenir à l'appel:
cela fait appel à l'aide d':
ce qui conduit à :
et c'est la méthode native....
je n'ai pas le temps maintenant d'creusé dans c jusqu'à ce que je disséquer appel reste, je dois suspendre ma réponse.
mais la meilleure façon de vérifier si le service est en cours d'exécution est de créer bind (si bind est pas créé le service n'existe pas) - et d'interroger le service à propos de son état par l'intermédiaire de la liaison (en utilisant stockées internes, le drapeau de l'état).
mise à jour 23.06.2018
j'ai trouvé ces intéressantes:
en bref 🙂
"Fournir un classeur déjà lié service. Cette méthode est synchrone et de ne pas commencer la cible de service s'il n'est pas présent."
public IBinder peekService(But de service, Chaîne resolvedType,
Chaîne callingPackage) throws RemoteException;
À votre Service Sous-Classe Static Boolean pour obtenir l'état du Service, comme illustré ci-dessous.
MyService.kt
MainActivity.kt
Mon kotlin de conversion de la
ActivityManager::getRunningServices
en fonction des réponses. Mettre cette fonction dans une activitéVeuillez utilisez ce code.
De prendre facilement les gars... 🙂
Je pense que la solution la plus adaptée est la tenue d'une paire clé-valeur dans
SharedPreferences
sur si le service est en cours d'exécution ou non.Logique est très simple; dans la position souhaitée dans votre classe de service, mettre une valeur booléenne qui va agir comme un drapeau pour vous de savoir si le service est en cours d'exécution ou non. Alors lisez cette valeur où vous le voulez dans votre application.
Un exemple de code que j'utilise dans mon application est ci-dessous:
Dans ma classe de Service (Un service pour les Flux Audio), j'exécute le code suivant lorsque le service est en place;
Puis dans toute activité de ma demande, je suis à la vérification de l'état du service avec l'aide du code suivant;
Pas d'autorisations spéciales, pas de boucles... moyen Facile, propre solution 🙂
Si vous avez besoin d'informations supplémentaires, veuillez consulter le lien
Espère que cette aide.
onDestroy
d'être appelé.