Процесс службы прекращается после удаления приложения из панели приложений.

Я запускаю службу (или перезапускаю запущенную службу) при запуске операции, используя:

Intent intent = new Intent(this, MyService.class); startService(intent);

Позже, основываясь на определенных действиях, та же самая деятельность связывается с сервисом, используя

bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);

И когда деятельность уничтожается, я звоню

unbindService(mConnection);

Ранее служба использовалась для перезапуска, когда я убивал ту же активность / приложение из панели приложений и показывал "запущен сервис 1-го процесса 1" под запущенными приложениями.

Теперь служба не перезапускается при уничтожении того же действия / приложения.

И я получаю сообщение "0 процесс 1 служба запущена", что означает, что служба на самом деле не работает.

Служба не перезапускается при закрытии приложения. Моя заявка состоит из одного занятия. Также служба успешно запускается при запуске после загрузки системы.

Почему процесс службы убивается, когда я запускаю его с помощью startService()??

редактировать

Служба использовалась для перезапуска ранее после того, как я закрыл приложение из панели приложений. Но теперь вдруг с тем же кодом, это не так. Это происходит и с другими приложениями, когда я их закрываю. например.

6 ответов

Решение

Вот обходной путь, с которым я столкнулся и хорошо работающий для перезапуска службы, если ее процесс прерывается при закрытии приложения. В вашем сервисе добавьте следующий код.

Я наткнулся на этот обходной путь в этой теме.

@Override
public void onTaskRemoved(Intent rootIntent){
    Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
    restartServiceIntent.setPackage(getPackageName());

    PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
    AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    alarmService.set(
    AlarmManager.ELAPSED_REALTIME,
    SystemClock.elapsedRealtime() + 1000,
    restartServicePendingIntent);

    super.onTaskRemoved(rootIntent);
 }

Кажется, это ошибка, что процесс приложения убит. Служба не имеет смысла запускаться, если ее процесс завершен.

Помните об этом: onDestroy не всегда вызывается. Вы не должны ставить код таким образом.
Когда действие принудительно закрывается или закрывается системой ненормально, onDestroy не вызывается.

К сожалению, это сложная проблема из-за того, как работает Android. Существует ряд стратегий, каждая из которых решает разные части проблемы. Для достижения наилучших результатов объедините несколько стратегий вместе.

Обратите внимание, что некоторые из этих стратегий больше не нужны в более поздних версиях Android.

1. Начните деятельность

Что делать

Взято из сервиса Foreground, убито при получении трансляции после того, как активность была удалена из списка задач:

На переднем плане службы:

  @Override
    public void onTaskRemoved( Intent rootIntent ) {
       Intent intent = new Intent( this, DummyActivity.class );
       intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
       startActivity( intent );
    }

В манифесте:

  <activity
    android:name=".DummyActivity"
    android:theme="@android:style/Theme.NoDisplay"
    android:enabled="true"
    android:allowTaskReparenting="true"
    android:noHistory="true"
    android:excludeFromRecents="true"
    android:alwaysRetainTaskState="false"
    android:stateNotNeeded="true"
    android:clearTaskOnLaunch="true"
    android:finishOnTaskLaunch="true"
    /> 

(Если ваш сервис находится в другом процессе, установите для этого процесса тот же процесс.)

В DummyActivity.java:

  public class DummyActivity extends Activity {
        @Override
        public void onCreate( Bundle icicle ) {
            super.onCreate( icicle );
            finish();
        }
    }

Побочные эффекты

Вызывает закрытие активности последних событий. Как правило, смахивание приложения не закрывает активность последних.

Недостатки

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

объяснение

Когда вы удаляете / удаляете свое приложение, появляется флаг waitingToKill установлено. Пока этот флаг установлен, Android может убить процесс в любой момент в будущем, например, при получении трансляции. Начало действия снимает этот флаг.

2. Спам BroadcastReceiver с трансляциями на переднем плане

Что делать

Объедините это с вашим сервисным кодом:

if (Build.VERSION.SDK_INT >= 16) {
    Intent intent = new Intent(this, DummyReceiver.class);
    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);

    //This seems to be timing-related; the more times we do this,
    //the less likely the process gets killed
    for (int i = 0; i < 50; ++i)
        sendBroadcast(intent);
}

Создать фиктивный приемник вещания:

public class DummyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {}
}

Добавьте получателя в свой манифест:

<receiver android:name=".DummyReceiver" />

Побочные эффекты

Может вызвать небольшую (~250 мс) задержку / зависание при удалении задачи из экрана последних.

Недостатки

Это только поддерживает процесс, пока он получает трансляции. waitingToKill флаг все еще установлен, так что процесс может все еще быть убит впоследствии, например, когда получено широковещание.

объяснение

Если ваш процесс не работает с приоритетом переднего плана, Android попытается немедленно его убить. Прием передач переднего плана временно предотвращает это, что приводит к waitingToKill флаг устанавливается вместо

3. Не привязывайтесь к услугам

Связывание со службой, по-видимому, увеличивает вероятность того, что процесс службы будет убит сразу после удаления задачи.

ОнДестрой не всегда называется. Основная проблема в вашем случае заключается в том, что вы не можете запустить службу, когда приложение закрыто, в это время ОС Android (в некоторых ОС) убьет службу. Если вы не можете перезапустить службу, то вызовите диспетчер тревог, чтобы запустить приемник, например этот,

Манифест есть,

         <service
            android:name=".BackgroundService"
            android:description="@string/app_name"
            android:enabled="true"
            android:label="Notification" />
        <receiver android:name="AlarmReceiver">
            <intent-filter>
                <action android:name="REFRESH_THIS" />
            </intent-filter>
        </receiver>

IN Main Activty запускает систему управления тревогами таким образом,

String alarm = Context.ALARM_SERVICE;
        AlarmManager am = (AlarmManager) getSystemService(alarm);

        Intent intent = new Intent("REFRESH_THIS");
        PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);

        int type = AlarmManager.RTC_WAKEUP;
        long interval = 1000 * 50;

        am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);

это вызовет reciver и reciver is,

public class AlarmReceiver extends BroadcastReceiver {
    Context context;

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;

        System.out.println("Alarma Reciver Called");

        if (isMyServiceRunning(this.context, BackgroundService.class)) {
            System.out.println("alredy running no need to start again");
        } else {
            Intent background = new Intent(context, BackgroundService.class);
            context.startService(background);
        }
    }

    public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        if (services != null) {
            for (int i = 0; i < services.size(); i++) {
                if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
                    return true;
                }
            }
        }
        return false;
    }
}

И этот Alaram Reciver вызывает один раз, когда Android-приложение открыто и когда приложение закрыто. Так что сервис такой,

public class BackgroundService extends Service {
    private String LOG_TAG = null;

    @Override
    public void onCreate() {
        super.onCreate();
        LOG_TAG = "app_name";
        Log.i(LOG_TAG, "service created");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(LOG_TAG, "In onStartCommand");
        //ur actual code
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Wont be called as service is not bound
        Log.i(LOG_TAG, "In onBind");
        return null;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Log.i(LOG_TAG, "In onTaskRemoved");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(LOG_TAG, "In onDestroyed");
    }
}

Я знаю, что этот вопрос старый, но недавно я столкнулся с этой проблемой, и внезапно мой сервис остановился при закрытии приложения. Раньше все работало нормально. Эта проблема потратила много времени. Для других, у которых есть подобные проблемы, убедитесь, что ВАШЕ ФОНОВОЕ ОГРАНИЧЕНИЕ ДАННЫХ ОТКЛЮЧЕНО. Это была проблема, которая у меня была, и она действительно имеет смысл, так как когда фоновые данные ограничены, фоновый процесс не запускается.

Когда нет привязки к сервису или хорошо установленный передний план, тогда система Android распознает сервис как неиспользуемую службу перегрузки, которая должна быть закрыта. Вот лучший способ сохранить ваш сервис, даже если приложение закрыто: AlarmManager или Service

Другие вопросы по тегам