2010-12-14 22 views
18

Jaki byłby najlepszy sposób sprawdzenia, czy usługa Android jest uruchomiona? Zdaję sobie sprawę z interfejsu API ActivityManager, ale wygląda na to, że użycie interfejsu API nie jest zalecane w przypadku scenariuszy podobnych do moich (source). Jestem również świadomy możliwości użycia zmiennych globalnych/trwałych w celu utrzymania stanu usługi.Android: Sprawdź, czy usługa jest uruchomiona. bindService

Próbowałem użyć bindService z flag ustawionych na 0, ale mam takie same problemy jak osoby na źródłowego łącza (jedynym wyjątkiem był, starałem się bindService z usługi lokalnej).

następujące wywołanie

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

zawsze zwraca true, ale nie zostanie podłączony. Czy to oczekiwane zachowanie? Wydaje mi się, że bindService powinien zwrócić wartość false, jeśli usługa nie jest jeszcze uruchomiona (nie jest, sprawdziłem to) lub jeśli flaga BIND_AUTO_CREATE nie jest ustawiona (ponownie, nie jest).

Odpowiedz

10

Mam ten sam problem; wydaje się, że najlepiej znanym rozwiązaniem jest stworzenie publicznej statycznej wartości boolowskiej w WhateverService, ustawionej na true podczas onCreate (lub onStartCommand, do wyboru) i false podczas onDestroy. Możesz wtedy uzyskać do niego dostęp z dowolnej innej klasy w tym samym pakiecie APK. Może to być jednak wyścigowe. W Androidzie nie ma API, aby sprawdzić, czy usługa jest uruchomiona (bez efektów ubocznych): Zobacz: http://groups.google.com/group/android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d

Przypuszczam, że stan wyścigu wynika z faktu, że system operacyjny może zabić usługę zdalną (w innym procesie) w dowolnym momencie . Sprawdzanie usługi lokalnej (ten sam proces), jak zasugerowano powyżej, wydaje mi się wolne od wyścigów - jeśli system operacyjny zabija usługę, zabija również sprawdzone jej statusy.

0

Co planujesz zrobić, jeśli usługa jest uruchomiona/nie działa? Dlaczego nie zadzwonić pod numer startService(). To utworzy go, jeśli nie działa, a jeśli tak, to wywoła jego metodę onStart().

+1

Powiedzmy, że chciałbym lubię wydrukować wiadomość "Usługa jest uruchomiona" lub "Usługa nie działa". Właśnie dlatego muszę uzyskać informacje, czy usługa jest uruchomiona, czy nie. Nie mogę tego zrobić, dzwoniąc do usługi startService. – Igor

+0

Ale dlaczego musisz wydrukować tę wiadomość? Są tylko 2 rzeczy, które możesz zrobić, jeśli usługa nie działa. Albo zacznij, albo nie. – Falmarri

+1

Ponieważ chcę poinformować użytkownika, czy usługa jest uruchomiona, czy nie. Użytkownik powinien ręcznie uruchomić i zatrzymać usługę (naciskając klawisz.).Gdy użytkownik zamknie działanie (przycisk BACK), usługa powinna pozostać uruchomiona. A aktywność powinna wiedzieć, kiedy użytkownik uruchomi ją następnym razem, że usługa jest już uruchomiona. – Igor

1

Miałem taką samą potrzebę i stwierdziłem, że uruchamianie .bindService z czymś innym jest już związane, że spowoduje to błędy. Zrobiłem to tuż przed uruchomieniem .bindService

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

To tylko sprawdza, czy jesteś związany z usługą. Nie, jeśli to się zaczęło, czy nie. – Falmarri

11

użyć udostępnionego preferencji zapisać serwis działa flagę.

@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

To nie jest dobry pomysł, SharedPreferences są przechowywane w pamięci nieulotnej, więc jeśli z jakiegoś powodu urządzenie się zawiesi lub straci moc, wtedy 'onDestroy' nie zostanie wywołany, a przy następnym uruchomieniu aplikacja uzna, że ​​usługa jest uruchomiona chociaż tak nie jest. – satur9nine

+0

Tak, zgadzam się. SharedPreferences nie są do tego przeznaczone. Ale uruchomienie usługi pref można usunąć przy starcie aplikacji. Innym sposobem: usługa przechowywania działa bool var w obiekcie aplikacji. –

+0

onDestroy nie zawsze nazywa się – Nepster

2

Inna metoda:

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

Kiedy używam powyższego kodu, to daje mi informacje tylko o uruchomionych usługach systemu. Szukam wszystkich usług, w tym jednej, którą stworzyłem – user1810931

0

w swojej działalności u można po prostu sprawdzić go za pomocą instancji usługi w moim przypadku odbywa się to za pomocą

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()); 
    } 
Powiązane problemy