Подтвердить что ты не робот

Android: проверьте, работает ли служба. bindService

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

Использовать общую привилегию для сохранения флага службы.

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 7

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

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