Що станеться, якщо Служба Android запускається кілька разів?


120

Якщо у мене є такий код:

Intent intent = new Intent(this,DownloadService.class);     
for(int i=0;i<filesArray.length;i++){        
     startService(intent);          
}

У цьому код DownloadServiceпоширюється IntentService.

Отже, коли я телефоную, startService(intent)чи означає це, що я запускаю нову послугу кожного разу, коли startService(intent)вона викликається, або це означає, що DownloadServiceзапускається один раз, а потім кожен раз, коли я startService(intent)її закликаю , просто передасть інший намір з іншим startId.

Чи має це сенс, і яка з них є справою?

Відповіді:


167

Служба працюватиме лише в одному екземплярі. Однак кожного разу, коли ви запускаєте послугу, onStartCommand()метод викликається.

Це задокументовано тут


1
Дякую. Там же зазначено: "Метод startService () повертається негайно, і система Android викликає метод onStartCommand () служби. Якщо служба ще не працює, система спочатку викликає onCreate (), а потім викликаєStartCommand ()." Отже, якщо служба вже запущена, система пропустить метод onCreate () і зателефонує лише onStartCommand () або що?
bytebiscuit

Я насправді не знаю, але я впевнений, що це так (робить багато сенсу, щоб не дзвонити, onCreate()якщо служба вже створена). Неважко визначити, чи вводиться ви Log.i()в обидва зворотні виклики та перевіряєте LogCat.
Філіп Вендт

Щойно це зробив ... і як не дивно, він запускає onCreate після останнього запускуService () дзвінка !!!
bytebiscuit

15
Це тому, що startService()є асинхронним. Тож, поки ви займаєтеся циклами дзвінків, служба сама не отримала жодних ресурсів і ще не почала працювати.
Філіп Вендт

1
@neelabh не "одразу", для запуску послуги потрібен певний час, і цикл "for" все ще буде працювати і викликати послугу знову і знову, тому перші спроби ще не знайдуть жодної служби, що працює ... тож метод startService () буде викликаний пару разів, поки не завершиться запуск служби. Вибачте, будь ласка, моя погана англійська.
mzalazar

21

Абсолютно правильно. Для процесу подання заявки створено лише один екземпляр Сервісу. І коли ви StartService();знову зателефонуєте , тоді onStartCommand()викликується лише новий onStartCommand()метод і передається метод

Примітка: onCreate() знову не викликається.

Про bindService()багаторазовий дзвінок :

Коли ви телефонуєте bindService() кілька разів, то для сервісу знову використовується лише один екземпляр, а Android Runtime повертає той же об’єкт IBinder клієнту.

Значить, onBind()не називається багаторазово. І щойно кешований об'єкт IBinder повертається.


Чи onStop()потрібно викликати кожного відповідного onStartCommand?
ІгорГанапольський

6
@IgorGanapolsky: Перш за все, у службі немає такого способу зворотного виклику onStop (). Нам потрібно зателефонувати stopService () або stopSelf (), щоб зупинити послугу. І коли onStartCommand () було викликано кілька разів для кількох намірів, тоді нам потрібно викликати лише stopSelf () або stopService () лише один раз. Якщо ви використовуєте IntentService, вам слід зателефонувати stopSelfResult (int id), передаючи ідентифікатор start запиту від onHandleIntent (), який зупинить відповідний запит ідентифікатора start, який був розміщений у робочій черзі IntentService. Сподіваюся, це допомагає.
Аніш Міттал

8

Додавання додаткової інформації до вищезазначених відповідей, яка може бути корисною для інших, полягає в тому, startIdщо отриманий onStartCommand()метод відрізняється для кожного startService()дзвінка.

Крім того, якщо ми пишемо для циклу, як згадувалося вище, код написаний в onHandleIntent() , виконується стільки разів, як визначено частотою циклу, але послідовно, а не паралельно.

Концепція полягає у IntentServiceстворенні робочої черги та кожного запиту, який startService()викликає, onStartCommand()який, у свою чергу, зберігає наміри у робочій черзі, а потім передає наміри по одному onHandleIntent().


2

Відповідно до док .

Метод startService () повертається негайно, а система Android викликає сервіс методом onStartCommand (). Якщо послуга вже не працює, система спочатку викликає onCreate (), а потім викликаєStartCommand ().

і

Кілька запитів на запуск послуги призводять до декількох відповідних дзвінків до служби onStartCommand (). Однак для його припинення потрібен лише один запит на припинення послуги (за допомогою stopSelf () або stopService ()).

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