Comment puis-je vérifier si un service de fond (sur Android) est en cours d’exécution ? Je veux un androïde activité qui fait basculer l’état du service--me permet d’allumer si elle est éteinte et off si c’est sur.
Réponses
Trop de publicités?J'utilise la suite de l'intérieur d'une activité:
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
Et d'appeler à l'aide:
isMyServiceRunning(MyService.class)
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 par le biais de 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 vous tuer processus ou des rappels sont appelés ou non. Veuillez noter que le "tuables" colonne dans le cycle de vie de la table des événements dans Android documentation.
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:
EDIT (pour mémoire):
Voici la solution proposée par hackbod:
Si votre code client et serveur fait partie de la même chose .apk et vous êtes la liaison au service d'une Intention (qui spécifie le exact classe de service), alors vous pouvez simplement demander à votre service un variable globale lorsqu'il est en cours d'exécution que votre client peut vérifier.
Nous avons délibérément de ne pas avoir une API pour vérifier si un service est la course parce que, presque sans faute, lorsque vous voulez faire quelque chose comme ça, vous vous retrouvez avec des conditions de course dans votre code.
Je voudrais proposer un petit complément à ce vieux fil.
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.
L'appel de 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é : je.e l'est pas istanciation à tous de l'instance du singleton par des méthodes statiques. La statique de la méthode getInstance de votre service/singleton, il suffit de retourner 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 comme isInstanceCreated() : boolean méthode.
Le code ressemblera à :
public class MyService extends Service
{
private static MyService instance = null;
public static boolean isInstanceCreated() {
return instance != null;
}//met
@Override
public void onCreate()
{
instance = this;
....
}//met
@Override
public void onDestroy()
{
instance = null;
...
}//met
}//class
Cette solution est élégante, mais 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 essayer encore, mais espérons que cela fonctionne)
if(startService(someIntent) != null) {
Toast.makeText(getBaseContext(), "Service is already running", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getBaseContext(), "There is no service running, starting service..", Toast.LENGTH_SHORT).show();
}
la startService méthode renvoie une Nomcomposant de l'objet, si il est déjà en cours d'exécution de service, si ce n'est la valeur null sera retourné.
Ce n'est pas comme la vérification de je pense, parce que son départ du service, de sorte que vous pouvez ajouter stopService(someIntent);
en vertu du code