2010-12-14 13 views
18

¿Cuál sería la mejor manera de comprobar si se está ejecutando un servicio de Android? Soy consciente de la API ActivityManager, pero parece que no se recomienda el uso de la API para los escenarios similares al mío (source). También soy consciente de la posibilidad de usar variables globales/persistentes para mantener el estado de un servicio.Android: compruebe si el servicio se está ejecutando a través de. bindService

He intentado utilizar bindService con indicadores establecidos a 0, pero tengo los mismos problemas que la persona en el fuente de enlace (la única excepción fue, yo estaba tratando el bindService con un servicio local).

la siguiente llamada

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

siempre devuelve cierto, pero no conectarse. Es este el comportamiento esperado? Me parece que bindService debe devolver falso si el servicio no se está ejecutando (no lo está, lo he comprobado) o si el indicador BIND_AUTO_CREATE no está configurado (de nuevo, no lo está).

Respuesta

10

Tengo el mismo problema; parece que la solución más conocida es crear un booleano público estático en WhateverService, establecido en true durante onCreate (o onStartCommand, su elección) y falso durante onDestroy. A continuación, puede acceder desde cualquier otra clase en la misma apk. Sin embargo, esto puede ser raro. No hay API dentro de Android para verificar si un servicio se está ejecutando (sin efectos secundarios): Consulte http://groups.google.com/group/android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d

Supongo que la condición de carrera proviene del hecho de que el sistema operativo puede matar a un servicio remoto (en otro proceso) en cualquier momento . Verificar un servicio local (el mismo proceso), como se sugirió anteriormente, parece libre de raza para mí: si el sistema operativo mata el servicio, también mata lo que verificó su estado.

0

¿Qué piensas hacer si el servicio se está ejecutando o no se está ejecutando? ¿Por qué no simplemente llama al startService(). Eso lo creará si no se está ejecutando, y si lo es, llamará a su método onStart().

+1

Digamos que lo haría desea imprimir un mensaje "El servicio se está ejecutando" o "El servicio no se está ejecutando". Es por eso que tengo que obtener la información si el servicio se está ejecutando o no. No puedo hacer eso llamando a startService. – Igor

+0

¿Pero por qué tiene que imprimir este mensaje? Solo hay dos cosas que puede hacer si el servicio no se está ejecutando. Empieza o no. – Falmarri

+1

Porque me gustaría informar al usuario si el servicio se está ejecutando o no. El usuario debe iniciar y detener el servicio de forma manual (mediante la pulsación de un botón).Cuando el usuario cierra la actividad (botón ATRÁS), el servicio debe seguir funcionando. Y la actividad debe saber, cuando el usuario la inicia la próxima vez, que el servicio ya se está ejecutando. – Igor

1

Tuve la misma necesidad y encontré que ejecutar .bindService con algo más ya enlazado, que causaría errores. Lo hice bien antes de ejecutar .bindService

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

Esto solo comprueba si está obligado al servicio. No si comenzó o no. – Falmarri

11

Usar una preferencia compartida para guardar servicio que se ejecuta bandera.

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

No es una buena idea, las Preferencias Compartidas persisten en el almacenamiento no volátil, por lo que si por algún motivo el dispositivo se bloquea o pierde potencia, no se invocará su 'onDestroy' y la próxima vez que inicie su aplicación pensará que el servicio se está ejecutando a pesar de que no lo es. – satur9nine

+0

Sí, estoy de acuerdo. SharedPreferences no están destinados para ello. Pero, el servicio que se ejecuta pref se puede eliminar al inicio de la aplicación. Otra forma: servicio de tienda ejecutando bool var en el objeto Aplicación. –

+0

onDestroy no siempre llama a – Nepster

2

Otro método:

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

Cuando uso el código anterior, me da información de solo los servicios que ejecutan el sistema. Estoy buscando todos los servicios, incluido el que creé – user1810931

0

en su actividad u simplemente puede comprobar mediante el uso de instancia de su servicio en mi caso lo he hecho usando

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()); 
    } 
Cuestiones relacionadas