web-dev-qa-db-ger.com

Android: Prüfen Sie, ob der Dienst über läuft. bindService

Was wäre der beste Weg, um zu überprüfen, ob ein Android-Dienst ausgeführt wird? Ich kenne die ActivityManager-API, aber es scheint, dass die Verwendung der API für die Szenarien ähnlich wie bei mir ( source ) nicht empfohlen wird. Ich bin mir auch der Möglichkeit bewusst, globale/persistente Variablen zu verwenden, um den Status eines Dienstes aufrechtzuerhalten.

Ich habe versucht, bindService mit Flags zu verwenden, die auf 0 gesetzt sind, aber ich hatte die gleichen Probleme wie die Person auf dem source link (die einzige Ausnahme war, dass ich bindService mit einem lokalen Dienst ausprobierte).

Der folgende Anruf

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

gibt immer "true" zurück, wird jedoch nicht verbunden. Ist das das erwartete Verhalten? Es scheint mir, dass bindService false zurückgeben sollte, wenn der Dienst nicht bereits ausgeführt wird (dies ist nicht der Fall, ich habe das geprüft) oder wenn das BIND_AUTO_CREATE-Flag nicht gesetzt ist (wiederum nicht).

20
Igor

Ich habe das gleiche Problem. Die bekannteste Lösung scheint die Erstellung eines öffentlichen statischen Booleschen Objekts in WhateverService zu sein, das während onCreate (oder onStartCommand Ihrer Wahl) auf true und während onDestroy auf false gesetzt wird. Sie können dann von jeder anderen Klasse in derselben apk darauf zugreifen. Dies kann jedoch rennhaft sein. Es gibt keine API in Android, um zu überprüfen, ob ein Dienst ausgeführt wird (ohne Nebenwirkungen): Siehe http://groups.google.com/group/Android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d

Ich nehme an, die Race-Bedingung beruht auf der Tatsache, dass das Betriebssystem jederzeit einen Remote-Service (in einem anderen Prozess) beenden kann. Die Überprüfung eines lokalen Dienstes (derselbe Prozess), wie oben vorgeschlagen, scheint mir rassenfrei zu sein - wenn das Betriebssystem den Dienst beendet, tötet es auch das, was seinen Status überprüft hat.

10
bryanr

Verwenden Sie eine gemeinsam genutzte Einstellung, um das Dienstflag zu speichern.

@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);
}

Eine andere Methode:

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;
}

Ich hatte das gleiche Bedürfnis und stellte fest, dass das Ausführen von .bindService mit etwas anderem bereits gebunden ist und Fehler verursachen würde. Ich habe das direkt gemacht, bevor .bindService ausgeführt wurde

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

in Ihrer Aktivität können Sie es einfach überprüfen, indem Sie Instanz Ihres Dienstes verwenden. In meinem Fall habe ich es verwendet 

  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