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 () буде викликаний у наступному екземплярі служби з нульовим наміром, а не взагалі. Служби, які використовують цей режим, повинні завжди перевіряти цю справу та вирішувати її належним чином.

START_NOT_STICKY говорить про те, що після повернення з onStartCreate (), якщо процес буде вбито, не маючи інших команд запуску для доставки, сервіс буде зупинено замість перезапуску. Це має набагато більше сенсу для служб, які призначені для запуску лише під час виконання відправлених їм команд. Наприклад, послуга може бути запущена кожні 15 хвилин від сигналу тривоги, щоб опитувати деякий стан мережі. Якщо його вбивають під час виконання цієї роботи, було б краще просто дозволити його зупинити і розпочати роботу наступного разу, коли спрацює тривога.

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


1
Як уникнути подвійного виклику до taskStart (наміру, startId); як будуть називатися onStart () і onStartCommand? це гарний дизайн? @Frank Leigh
Sazzad Hissain Khan

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

Відповідь KISS

Різниця:

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


не пощастило хлопцям .. Мені не вдалося співвіднести документацію словом мирянина. Я хотів би пов'язати зі сценарієм у реальному часі. Я хотів би показати приклад на пристрої. щоб вони могли зрозуміти легше.
prago

для START_STICKY та START_NOT_STICKY onStartCommand () буде виконано лише один раз і вийде з нього. Я пішов через обраний зразок u, але я сумніваюся, скільки разів onStartCommand () буде виконаний. якщо я перезавантажую START_STICKY і все-таки спробую відновити службу, чи буде служба виконувати onStartCommand тоді ??
prago

що відбувається з діяльністю, коли служба заново створена? Чи відтворена також діяльність?
ransh

Напевно, ми ніколи не дізнаємось
Денні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.