web-dev-qa-db-fra.com

Android: Vérifiez si le service est en cours via. bindService

Quel serait le meilleur moyen de vérifier si un service Android est en cours d'exécution? Je connais l’API ActivityManager, mais il semble que son utilisation n’est pas recommandée pour les scénarios similaires au mien ( source ). Je suis également conscient de la possibilité d'utiliser des variables globales/persistantes pour maintenir l'état d'un service.

J'ai essayé d'utiliser bindService avec les indicateurs définis sur 0, mais j'ai les mêmes problèmes que la personne sur le lien source (la seule exception était que j'essayais la bindService avec un service local).

L'appel suivant

getApplicationContext().bindService(new Intent(getApplicationContext(),
        MyService.class), mServiceConnection, 0);

renvoie toujours true, mais ne se connecte pas. Est-ce le comportement attendu? Il me semble que bindService devrait retourner false si le service n'est pas déjà en cours d'exécution (ce n'est pas le cas, j'ai vérifié cela) ou si l'indicateur BIND_AUTO_CREATE n'est pas défini (encore une fois, ce n'est pas le cas).

20
Igor

J'ai le même problème; Il semble que la solution la plus connue consiste à créer un booléen statique public dans WhateverService, défini sur true lors de onCreate (ou onStartCommand, à votre choix) et sur false lors de onDestroy. Vous pouvez ensuite y accéder depuis n'importe quelle autre classe du même apk. Cela peut être raciste si. Il n'y a pas d'API dans Android pour vérifier si un service est en cours d'exécution (sans effets secondaires): voir http://groups.google.com/group/Android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d

Je suppose que la condition de concurrence vient du fait que le système d'exploitation peut tuer un service distant (dans un autre processus) à tout moment. Vérifier un service local (même procédure), comme suggéré ci-dessus, ne me semble pas être une race. Si l'OS tue le service, il tue également celui qui a vérifié son statut.

10
bryanr

Utilisez une préférence partagée pour enregistrer l'indicateur de service en cours.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    int res = super.onStartCommand(intent, flags, startId);
    setRunning(true);
    return res;
}

@Override
public void onDestroy() {
    super.onDestroy();
    setRunning(false);
}

private void setRunning(boolean running) {
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    SharedPreferences.Editor editor = pref.edit();

    editor.putBoolean(PREF_IS_RUNNING, running);
    editor.apply();
}

public static boolean isRunning(Context ctx) {
    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
    return pref.getBoolean(PREF_IS_RUNNING, false);
}

Une autre méthode:

public static boolean isServiceRunning(Context ctx, String serviceClassName) {
    ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (TrackingService.class.getName().equals(serviceClassName)) {
            return true;
        }
    }
    return false;
}

J'ai eu le même besoin et j'ai constaté qu'exécuter .bindService avec quelque chose d'autre déjà lié pouvait causer des erreurs. Je l'ai fait avant d'exécuter .bindService

try{
    context.unbindService(fetch_connection);
} catch (IllegalArgumentException e){
    System.out.println("Unbinding didn't work. little surprise");
}
1
atraudes
0
Kevin Parker

dans votre activité, vous pouvez simplement le vérifier en utilisant une instance de votre service Dans mon cas, je l’ai fait en utilisant 

  button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent=new Intent(MainActivity.this, MyService.class);
            //startService(intent);
            bindService(intent,serviceConnection,BIND_AUTO_CREATE);
            if (myService!=null)
            {
                myService.RecData(editText.getText().toString());
            }
        }
    });
}

ServiceConnection serviceConnection=new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        Toast.makeText(MainActivity.this,"onServiceConnected called",Toast.LENGTH_SHORT).show();
        MyService.MyBinder myBinder= (MyService.MyBinder) iBinder;
        myService= myBinder.getServiceInstant();
        myService.SetActivity(MainActivity.this);
        myService.RecData(editText.getText().toString());
    }
0
Hrishikesh Jadhav