2010-12-14 6 views
18

Что было бы лучшим способом проверить, работает ли Android-сервис? Я знаю API ActivityManager, но похоже, что использование API не рекомендуется для сценариев, подобных моим (source). Я также знаю о возможности использования глобальных/постоянных переменных для поддержания состояния службы.Android: проверьте, работает ли служба. bindService

Я пытался использовать bindService с флагами в 0, но у меня те же проблемы, что и лицо на источника связи (единственное исключение было, я пытался в bindService с местной службой).

Следующий вызов

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

всегда возвращает истину, но не подключиться. Это ожидаемое поведение? Мне кажется, bindService должен возвращать false, если служба еще не запущена (это не так, я это проверил) или если флаг BIND_AUTO_CREATE не установлен (опять же, это не так).

ответ

10

У меня такая же проблема; кажется, наиболее известным решением является создание публичного статического булева в WhateverService, установленного в true во время onCreate (или onStartCommand, ваш выбор) и false во время onDestroy. Затем вы можете получить доступ к нему из любого другого класса в одном и том же apk. Однако это может быть расовым. В Android нет API для проверки работоспособности службы (без побочных эффектов): см. http://groups.google.com/group/android-developers/browse_thread/thread/8c4bd731681b8331/bf3ae8ef79cad75d

Я полагаю, что состояние гонки связано с тем, что ОС может убить удаленную службу (в другом процессе) в любое время , Проверка локальной службы (тот же процесс), как было предложено выше, кажется безгорной для меня - если ОС убивает службу, она убивает все, что проверяет ее статус.

0

Что вы планируете делать, если служба работает/не работает? Почему бы просто не позвонить startService(). Это создаст его, если он не запущен, и если он будет вызывать его метод onStart().

+1

Скажем, я бы например, для печати сообщения «Служба запущена» или «Служба не запущена». Вот почему я должен получить информацию, если служба работает или нет. Я не могу сделать это с вызовом startService. – Igor

+0

Но почему вы должны печатать это сообщение? Есть только 2 вещи, которые вы можете сделать, если служба не работает. Либо начните, либо нет. – Falmarri

+1

Потому что я хотел бы сообщить пользователю, работает ли служба или нет. Пользователь должен запустить и остановить службу вручную (с помощью нажатия кнопки).Когда пользователь закрывает действие (кнопка BACK), служба должна оставаться в рабочем состоянии. И активность должна знать, когда пользователь запустит ее в следующий раз, когда служба уже запущена. – Igor

1

У меня была такая же потребность, и я обнаружил, что работает .bindService с чем-то еще, уже связанным, что это вызовет ошибки. Я сделал это прямо перед запуском .bindService

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

Это просто проверяет, связаны ли вы с сервисом. Нет, если он запущен или нет. – Falmarri

11

Использовать совместно предпочтение сохранить флаг службы запуска.

@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

Это не очень хорошая идея. SharedPreferences сохраняются в энергонезависимой памяти, поэтому, если по какой-то причине устройство выходит из строя или теряет мощность, ваш 'onDestroy' не будет вызываться, а в следующий раз при запуске ваше приложение будет считать, что служба запущена хотя это не так. – satur9nine

+0

Да, согласен. SharedPreferences не предназначены для этого. Но при запуске приложения можно удалить служебный префикс. Другой способ: хранить службу, запускающую bool var в объекте Application. –

+0

onDestroy не всегда вызывает – Nepster

2

Другой метод:

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

Когда я использую приведенный выше код, он дает мне информацию только об обслуживании системы. Я ищу все услуги, включая тот, который я создал – user1810931

0

в своей деятельности и может просто проверить его с помощью экземпляр сервиса в моем случае я сделал это с помощью

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()); 
    } 
Смежные вопросы