Убит ли Android каждый сервис или весь процесс?

Многие из нас знают, что (в свободном выражении) a Service в Android будет убит системой, если он не называет Service.startForeground(). Но разве это вся история...?


Я работаю над некоторым устаревшим кодом, портируя приложение "системное" разрешение в Play Store. Это приложение имеет 5 справочных служб (которые не вызывают startForeground()), которые до сих пор были безопасными из-за "системного" разрешения, с которым приложение работало. Он был установлен на пользовательском устройстве. Из-за жестких временных рамок и бюджетов рефакторинг этих 5 в 1 не является краткосрочным решением, но мы хотели бы как можно скорее перейти к открытой бета-версии.

Короткий вопрос:

  • Если нет переднего плана Activity или Service, удаляет ли Android каждую отдельную фоновую службу или просто убивает сам процесс?

Ниже приведена информация из документов Android на Процессах и потоках, в которых обсуждается, как Android прекратит процессы, когда находится под давлением:

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

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


Общие знания говорят, что "Android убьет службу"

Личный опыт показал, что Android также убьет сам процесс (как описано в цитате выше). Это можно показать, сохранив объекты в объекте Application и отметив, что после перезапуска службы они повторно инициализируются.


С учетом вышеизложенного существует несколько вариантов решения проблемы:

1) Сделайте правильную вещь

Реорганизовать 5 сервисов в 1, работающих на разных потоках. Принесите 1 сервис на передний план. Проблема решена.

К сожалению, для этого нет бюджета, и мы предпочли бы найти быстрое решение из-за сроков выполнения проекта.

Это окончательное решение, которое будет реализовано в будущем в полном объеме.

2) Многие уведомления

Запустите каждую службу на переднем плане, каждая со своим значком Notification.

Это грязное решение, но оно будет работать на бета-полевых испытаниях, купив нам некоторое время.

Я думаю об этом как о подходе "грубой силы".

3) Процесс, защищенный одной службой

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

Это предотвратит "предотвращение" (т.е. вероятность того, что Android) будет убивать процесс.

Таким образом, сохранится все 5 сервисов.

4) Одна служба, чтобы управлять ими все

docs on Services сообщают нам, что если служба привязана к другому контексту, то

stopService() или stopSelf() фактически не останавливает службу до тех пор, пока все клиенты отсоединяют.

Если я привяжусь к другим службам из одной службы переднего плана, сохранит их все в живых?


Итак:

  • Удаляет ли Android каждую несвязанную, фоновую службу?
  • Или просто убить виртуальную машину, в которой работает приложение?

Update

После 18 41 часа тестирования №3 (процесс защищен одним сервисом) все 6 служб все еще работают (5 старых плюс 1 новый).

Итак, похоже, что Android будет убивать процесс, если не выполняются действия или службы переднего плана.

Ответы

Ответ 1

Если нет действия или службы переднего плана, удаляет ли Android каждый индивидуальное фоновое обслуживание или просто убивает процесс сам?

Android не убивает отдельных Activities или Services, что не имеет большого смысла. Например, если Activity находится в фоновом режиме, Android никогда не решит конкретно убить этого Activity. Неважно, какая именно Java Object находится в памяти, все те экземпляры Object имеют ту же участь: если они больше не нужны/используются, они будут собирать мусор. Люди часто говорят о том, что Activity убивают, когда он находится в фоновом режиме, и это действительно вводит в заблуждение, потому что они просто означают, что это может быть сбор мусора и в конечном итоге будет. Таким образом, сбор мусора - это то, что уничтожит конкретный экземпляр объекта. Это не имеет ничего общего с устройством с низкой памятью.

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

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

Общие знания говорят, что "Android убьет службу"

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


И теперь ваши решения:

Реорганизовать 5 сервисов в 1, работающих на разных потоках. Принесите 1 сервис на передний план. Проблема решена.

Это, очевидно, лучший вариант, но, как вы сказали, вы не можете реализовать это сейчас.

Запустите каждую услугу на переднем плане, каждая со своим значком уведомлений.

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

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

Это определенно может работать, я бы попробовал.

Документы по услугам говорят нам, что если служба привязана к другому контекст, затем

stopService() или stopSelf() фактически не останавливает службу до тех пор, пока все клиенты отсоединяют.

Если я привяжусь к другим службам из одной службы переднего плана, которые держат их всех живыми?

Это следующий лучший вариант, на мой взгляд.


Сначала я думал о начале каждого Service в своем собственном процессе. Но я не уверен, что это применимо к вам. Особенно, если вы хотите постоянно все Services работать. Преимущество запуска Service в его собственном процессе очевидно, что оно не зависит от остальной части приложения. Поэтому, даже если какая-то часть будет убита из-за ограничений памяти, остальная часть приложения будет продолжать работать в другом процессе.

Вы когда-нибудь думали об использовании наследования для решения проблемы? Это может быть самый простой способ реализовать ваш вариант 1).

Ответ 2

Каждое приложение для Android является вилкой процесса зиготы и имеет свой собственный процесс. Каждый процесс приложения может принимать больше действий и услуг: так определенно, убивая один процесс (например: kill PID), убьет все, что находится внутри.

По умолчанию служба находится в том же процессе своего приложения; однако возможно, чтобы служба работала в отдельном отдельном процессе с объявлением в манифесте:

<service android:name=".MyService"
     android:isolatedProcess=true />