Сбой службы Android после того, как приложение вышло из списка последних приложений

У меня есть служба, которая запускается (не привязывается) к действию. Если действие уничтожается (например, нажатием кнопки «Назад»), служба продолжает работать, это, конечно, предназначено. Однако, если я удаляю активность из списка «последние приложения», служба немедленно перезапускается. Это воспроизводимо, каждый раз, когда действие / приложение вырывается из списка, появляется новый вызов метода onCreate службы. Нет звонка в onDestroy между ними!

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

V/MainActivity(856): onDestroy // swipe out of the list I/ActivityManager(287): Killing 856:com.example.myapp/u0a10050: remove task W/ActivityManager(287): Scheduling restart of crashed service com.example.myapp/.TestService in 5000ms 

Код не примечателен, но здесь он

Мероприятия:

 public class MainActivity extends Activity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.v(TAG, "onCreate, starting service..."); startService(new Intent(this, TestService.class)); } @Override protected void onStart() { super.onStart(); Log.v(TAG, "onStart"); } @Override protected void onDestroy() { super.onDestroy(); Log.v(TAG, "onDestroy"); } //[...] } 

Обслуживание:

 public class TestService extends Service { private static final String TAG = "Service"; // onBind omitted @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.v(TAG, "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.v(TAG, "onDestroy"); } } 

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

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

Прокрутка приложения из списка недавних задач фактически убивает процесс операционной системы, в котором размещается приложение. Поскольку ваша служба работает в том же процессе, что и ваши действия, это фактически убивает службу. Он не вызывает onDestroy() в службе. Это просто убивает процесс. Boom. Мертв. Прошло. Ваш сервис не падает .

Поскольку ваша служба вернула START_STICKY из вызова в onStartCommand() , Android распознает, что ваша служба должна быть перезапущена и запланирована перезагрузка убитой службы. Однако, когда ваша служба будет перезапущена, она будет во вновь созданном процессе (вы можете увидеть onCreate() в службе), поэтому ей придется начинать работу снова и снова.

Правило №1: никогда не прокручивайте приложения из списка недавних задач 😉

Выбрав, вы НЕ УБЕДИТЕСЬ, что процесс приложения будет убит. Нет. Вы удаляете только задачу утилизации (или обратно). Задача приложения НЕ равна приложению.

Поэтому, если у вас есть какие-либо фоновые задания (нить, сервис и т. Д.), Привязанные к вашему заднему стекю, и у вас есть хорошая политика отмены, то соответствующие сервисы также будут исправлены.

Если вы убьете процессы приложения из диспетчера задач, это означает, что ваш процесс (при условии, что ваше приложение связано с одним процессом, который является обычным делом) будет удалено, и ваш jvm / sandbox также будет удален вместе с Все ресурсы относятся к этому процессу агрессивно со стороны системы.

Возможно, это может быть проблема с приемниками Broadcast, определенными в манифесте.

У вас есть фильтр приемника / намерения, определенный в манифесте на уровне приложения? У меня была такая же проблема, и это было вызвано заявлением получателя в манифесте на уровне приложения

Используйте * START_NOT_STICKY * как onStartCommand return

 @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.v(TAG, "onStartCommand"); return START_NOT_STICKY; }