Что произойдет, если служба 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.

Имеет ли это смысл, и какой из них так?

bytebiscuit
источник

Ответы:

167

Сервис будет работать только в одном экземпляре. Однако каждый раз, когда вы запускаете службу, onStartCommand()вызывается метод.

Это задокументировано здесь

Филипп Вендт
источник
1
Спасибо. Там также сказано: «Метод startService () немедленно возвращается, и система Android вызывает метод службы onStartCommand (). Если служба еще не запущена, система сначала вызывает onCreate (), а затем вызывает onStartCommand ()». Итак, если служба уже запущена, система пропустит метод onCreate () и вызовет только onStartCommand () или что?
bytebiscuit
Я действительно не знаю, но я почти уверен, что это так (очень важно не звонить, onCreate()если служба уже создана). Должно быть легко определить, вставили ли вы Log.i()оба обратных вызова и проверили ли LogCat.
Филипп Вендт
Только что сделал это ... и, как ни странно, он запускает onCreate после последнего вызова startService () !!!
bytebiscuit 05
15
Это потому, что startService()это асинхронно. Итак, пока вы зацикливаете вызовы, сама служба не получила ресурсов и еще не запустилась.
Филипп Вендт
1
@neelabh не "сразу", для запуска службы потребуется некоторое время, а цикл "for" будет все еще работать и снова и снова вызывать службу, поэтому первые попытки еще не обнаружат, что какая-либо служба еще работает ... поэтому метод startService () будет вызываться несколько раз до завершения запуска службы. Прошу прощения за мой плохой английский.
mzalazar 07
21

Совершенно верно. Для процесса приложения создается только один экземпляр службы. И когда вы вызываете StartService();снова, вызывается только метод, onStartCommand()и новое намерение передается onStartCommand()методу.

Примечание: onCreate() больше не вызывается.

О bindService()многократном звонке :

Когда вы вызываете bindService()несколько раз, снова только один экземпляр используется для службы, и Android Runtime возвращает тот же объект IBinder клиенту.

Значит, onBind()не вызывается несколько раз. И возвращается только что кешированный объект IBinder.

Аниш Миттал
источник
Должен ли onStop()быть вызван для каждого соответствующего onStartCommand?
Игорь Ганапольский 01
6
@IgorGanapolsky: Во-первых, такого метода обратного вызова onStop () в Service нет. Нам нужно вызвать stopService () или stopSelf (), чтобы остановить службу. И когда onStartCommand () вызывается несколько раз для нескольких целей, нам нужно вызвать только stopSelf () или stopService () только один раз. При использовании IntentService вы должны вызвать stopSelfResult (int id), передав начальный идентификатор запроса из onHandleIntent (), который остановит соответствующий запрос начального идентификатора, который был помещен в рабочую очередь IntentService. Надеюсь это поможет.
Аниш Миттал
8

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

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

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

Рахул Гупта
источник
2

Согласно документу :

Метод startService () немедленно возвращается, и система Android вызывает метод onStartCommand () службы. Если служба еще не запущена, система сначала вызывает onCreate (), а затем вызывает onStartCommand ().

и

Несколько запросов на запуск службы приводят к нескольким соответствующим вызовам onStartCommand () службы. Однако для ее остановки требуется только один запрос на остановку службы (с помощью stopSelf () или stopService ()).

Амир Резазаде
источник