START_STICKY и START_NOT_STICKY

Ответы:

371

Оба кода имеют значение только в том случае, если в телефоне не хватает памяти и он убивает службу, прежде чем она завершит работу. START_STICKYсообщает ОС, что необходимо восстановить службу после того, как у нее будет достаточно памяти, и onStartCommand()снова вызвать с нулевым намерением. START_NOT_STICKYговорит ОС, чтобы она больше не беспокоилась о воссоздании сервиса. Существует также третий код, START_REDELIVER_INTENTкоторый сообщает операционной системе о необходимости воссоздания службы и повторной доставки того же намерения onStartCommand().

Эта статья Дайан Хэкборн объясняет это гораздо лучше, чем официальная документация.

Источник: http://android-developers.blogspot.com.au/2010/02/service-api-changes-starting-with.html

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

START_STICKY в основном совпадает с предыдущим поведением, когда служба остается «запущенной» и позже будет перезапущена системой. Единственное отличие от предыдущих версий платформы состоит в том, что при перезапуске из-за прекращения процесса onStartCommand () будет вызываться для следующего экземпляра службы с нулевым Intent, а не вызываться вообще. Службы, которые используют этот режим, должны всегда проверять этот случай и обращаться с ним соответствующим образом.

START_NOT_STICKY говорит, что после возврата из onStartCreated (), если процесс завершается без оставшихся команд запуска для доставки, служба будет остановлена, а не перезапущена. Это имеет больше смысла для сервисов, которые предназначены для запуска только при выполнении команд, отправленных им. Например, служба может запускаться каждые 15 минут с момента тревоги для опроса какого-либо состояния сети. Если его убивают во время выполнения этой работы, лучше всего просто дать ему остановиться и начать работу при следующем срабатывании будильника.

START_REDELIVER_INTENT аналогичен START_NOT_STICKY, за исключением того, что процесс службы завершается до того, как он вызывает stopSelf () для данного намерения, это намерение будет повторно доставлено ему до его завершения (если только после некоторого количества попыток оно все еще не может завершиться, в этот момент система сдается). Это полезно для служб, которые получают команды работы и хотят убедиться, что они в конечном итоге завершают работу для каждой отправленной команды.

Фрэнк Ли
источник
1
Как избежать двойного вызова задачи handleStart (intent, startId); как и onStart () и onStartCommand будут называться? это хороший дизайн? @Frank Leigh
Саззад Хиссейн Хан
2
Что такое флаг по умолчанию, если он не указан?
Игорь Ганапольский
3
Если вы будете следовать «return super.onStartCommand (...);» вы увидите, что если ваша целевая версия SDK меньше ECLAIR (API5 = 2.0), по умолчанию возвращается START_STICKY_COMPATIBILITY, а с версии 2.0 и выше START_STICKY.
MikeL
1
Что вы подразумеваете под "без оставшихся команд запуска" START_NOT_STICKY?
Малвиндер Сингх
3
@FrankLeigh Я не согласен, что START_REDELIVER_INTENTэто как START_NOT_STICKY. Вместо этого это похоже наSTART_STICKY
CopsOnRoad
107

Поцелуй ответ

Разница:

START_STICKY

система попытается воссоздать ваш сервис после его уничтожения

START_NOT_STICKY

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


Стандартный пример:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}
Одед Брейнер
источник
5
Это на самом деле не правильно и запутанно. Ошибочно говорить: «служба убита», потому что можно подумать, что вы ссылаетесь на stopSelf или stopService, а вы явно ссылаетесь на процесс убит. Так что вам лучше использовать текстовый процесс в своем ответе.
Илья Газман
Привет, как я могу проверить START_REDELIVER_INTENT. Я только что проверил START_STICKYи убил приложение с помощью последних приложений. Тогда это отзыв службы. Но START_REDELIVER_INTENTникогда не звонил снова. Зачем?
Асиф Муштак
@IlyaGazman Я с уважением не согласен. Остановлены и убиты два совершенно разных слова. Этот ответ объясняет проблему правильно и просто.
NoHarmDan
23

Документация для START_STICKYи START_NOT_STICKYдовольно проста.

START_STICKY:

Если процесс этой службы прерван во время ее запуска (после возвращения из onStartCommand(Intent, int, int)), затем оставьте его в запущенном состоянии, но не сохраняйте доставленное намерение. Позже система попытается заново создать службу. Поскольку она находится в запущенном состоянии , он будет гарантированно вызывать onStartCommand(Intent, int, int) после создания нового экземпляра службы, если нет ожидающих выполнения команд запуска, которые будут доставлены в службу, он будет вызываться с объектом с нулевым намерением, поэтому вы должны позаботиться об этом.

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

Пример: Пример локальной службы

START_NOT_STICKY:

Если процесс этой службы прерван во время его запуска (после возвращения из onStartCommand(Intent, int, int)), и нет новых намерений запуска для его доставки, то выведите службу из состояния запуска и не создавайте заново до следующего явного вызова Context.startService(Intent)службы. не получит onStartCommand(Intent, int, int) вызов с nullнамерением, потому что он не будет перезапущен, если нет ожидающих намерений доставки.

Этот режим имеет смысл для вещей, которые хотят выполнить какую-то работу в результате запуска, но могут быть остановлены, когда находятся под нагрузкой памяти, и будут позже явно запускаться для выполнения дополнительной работы. Примером такой службы может служить тот, который запрашивает данные с сервера: он может планировать оповещение будильника на каждую Nминуту, если будильник запускает свою службу. Когда он onStartCommand(Intent, int, int)вызывается из сигнала тревоги, он планирует новый сигнал тревоги на N минут позже и порождает поток для создания сети. Если при выполнении этой проверки его процесс будет прерван, служба не будет перезапущена до тех пор, пока не сработает сигнализация.

Пример: ServiceStartArguments.java

Марвин Пинто
источник
не повезло, ребята .. Я не смог связать документацию на слово непрофессионала. Я хотел бы связать со сценарием в реальном времени. Я хотел бы показать пример на устройстве. чтобы они могли легче понять.
Праго
для START_STICKY и START_NOT_STICKY onStartCommand () будет выполнен только один раз и выйдет из него. Я прошел через пример, который вы указали, но я сомневаюсь, сколько раз будет выполняться onStartCommand (). если я восстановлю START_STICKY и все еще попытаюсь заново создать службу, будет ли служба выполняться по StartCommand тогда ??
Prago
что происходит с активностью, когда сервис воссоздается? Активность также воссоздана?
августа
Я думаю, мы никогда не узнаем
Денни