Сервис против IntentService на платформе Android

775

Я ищу пример того, что может быть сделано с помощью, IntentServiceчто не может быть сделано с Service(и наоборот)?

Я также считаю, что он IntentServiceработает в другом потоке, а Serviceнет. Итак, насколько я вижу, запуск службы в своем собственном потоке похож на запуск IntentService. Это верно?

roiberg
источник
45
IntentService is used for short tasks (etc) and a service is for long onesгде ты это прочитал?
njzk2
9
Кроме того, я предлагаю вам прочитать исходный код IntentService. Это ясно дает понять, что это такое и что он делает.
njzk2
1
Я отредактировал свой вопрос после того, как увидел ваш комментарий.
Ройберг
2
Ссылка в предыдущем комментарии (от greg7gkb) - отличное чтение.
DSlomer64

Ответы:

1350

Теджас Лагванкар написал хороший пост на эту тему. Ниже приведены некоторые ключевые различия между Service и IntentService.

Когда использовать?

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

  • IntentService можно использовать в длинных задачах , как правило, без связи с основным потоком. Если требуется связь, можно использовать обработчик основного потока или широковещательные намерения. Другой случай использования - когда требуются обратные вызовы (задачи, инициируемые намерением).

Как вызвать?

  • Служба запускается с помощью вызова метода startService().

  • IntentService срабатывает используя Намерение, создается новый рабочий поток и метод onHandleIntent()вызывается в этом потоке.

Запущен из

  • Обслуживание и IntentService могут быть вызваны из любого потока, активности или другого компонента приложения.

Работает на

  • Служба работает в фоновом режиме , но он работает на главном потоке приложения.

  • IntentService работает на отдельном потоке.

Ограничения / Недостатки

  • Служба может блокировать главный поток приложения.

  • IntentService не может выполнять задачи параллельно. Следовательно, все последовательные намерения будут помещены в очередь сообщений для рабочего потока и будут выполняться последовательно.

Когда остановиться?

  • Если вы внедряете Сервис , вы обязаны остановить сервис после завершения его работы, позвонив по телефону stopSelf()или stopService(). (Если вы хотите предоставить только привязку, вам не нужно реализовывать этот метод).

  • IntentService останавливает службу после того, как все запросы начала были обработаны, так что вы никогда не должны вызовом stopSelf().

Хосе Хуан Санчес
источник
11
Короче и приятнее, но лучше, если вы отредактируете свой ответ, включая пункты CommonsWare, так как многие читают только принятые или наиболее одобренные ответы
Shirish Herwade
12
@Darpan Сервис - это компонент приложения, который может выполнять длительные операции в фоновом режиме и не предоставляет пользовательский интерфейс. Служба работает в основном потоке своего хостинга. Сервис не создает свой собственный поток и не запускается в отдельном процессе (если не указано иное). Это означает, что, если ваша служба будет выполнять какие-либо работы с ЦП или блокировать операции (такие как воспроизведение MP3 или работа в сети), вы должны создать новый поток в службе для выполнения этой работы.
Хосе Хуан Санчес
8
«Служба IntentService должна быть запущена из основного потока». Ты уверен? Внутри моей MainActivity onCreate (), когда я вызываю IntentService из нового потока (код ниже), он все еще работает для меня. new Thread (new Runnable () {@Override public void run () {Intent intent = new Intent (context, HelloIntentService.class); startService (intent);}}). start ();
Ашок Биджой Дебнатх
9
@AshokBijoyDebnath Вы правы! В Услугах и IntentServices могут быть запущены из любого потока, активности или другого компонента приложения. Я только что отредактировал текст ответа, чтобы исправить эту проблему. Спасибо за ваше предложение по редактированию! :)
Хосе Хуан Санчес
2
Нет проблем, дерзайте!
Хосе Хуан Санчес
165

Если кто-то может показать мне пример чего-то, что может быть сделано с помощью IntentServiceи не может быть сделано с помощью Serviceи наоборот.

По определению это невозможно. IntentServiceэто подкласс Service, написанный на Java. Следовательно, все, что IntentServiceделает, Serviceможет сделать, включая соответствующие биты кода, который IntentServiceиспользует.

Запуск службы с собственным потоком подобен запуску IntentService. Это не?

Три основные особенности IntentService:

  • фоновый поток

  • автоматическая очередь Intents доставляется onStartCommand(), поэтому, если один Intentобрабатывается onHandleIntent()в фоновом потоке, другие команды выстраиваются в очередь в ожидании своей очереди

  • автоматическое отключение IntentServiceчерез вызов stopSelf(), когда очередь пуста

Все это может быть реализовано Serviceбез расширения IntentService.

CommonsWare
источник
6
Немного поздно, но я обнаружил, что Serviceвызов с startServiceможет выполняться только в течение примерно 10 секунд, прежде чем выбросить ANR - IntentServiceначало с трансляции намерения, похоже, не имеет этого ограничения
edthethird
16
@edthethird: это потому, что вы связывали основной поток приложения. Все методы жизненного цикла всех компонентов, включая onStartCommand()a Service, вызываются в главном потоке приложения. Вы не можете связать этот поток более чем на несколько миллисекунд, не заморозив свой пользовательский интерфейс, и если вы потратите много секунд, вы получите сервисный эквивалент ANR.
CommonsWare
3
Да, я прокомментировал слишком рано. Я выполнял работу onStartCommandвместо onHandleIntent- похоже, onStartCommandон запускается в потоке пользовательского интерфейса, однако для onHandleIntentвыполнения создается отдельный поток .
edthethird
3
@IgorGanapolsky: сам IntentServiceвызывает после onHandleIntent()возврата, если больше нет работы.
CommonsWare
1
Вопрос не в английском, а в программировании. Например, «я ЗАКРЫЛ приложение» не имеет точного определения, поэтому я не могу сказать вам, что происходит, когда это происходит. Я также не знаю, как «я ЗАКРЫЛ приложение» относится к «будет загружен через 1 час». Вы можете подумать о том, чтобы задать отдельный вопрос о переполнении стека, где вы можете предоставить минимальный воспроизводимый пример «будет загружен через 1 час». Там вы можете подробно объяснить, что означает «я ЗАКРЫЛ приложение» (например, что конкретно делает пользователь, чтобы закрыть приложение?).
CommonsWare
39

обслуживание

  • Вызвать startService()
  • Срабатывает от любого Thread
  • Работает на Main Thread
  • Может блокировать основной поток (пользовательский интерфейс). Всегда используйте поток внутри службы для долгой задачи
  • Как только задача выполнена, мы обязаны прекратить обслуживание, позвонив stopSelf()илиstopService()

IntentService

  • Он выполняет длинную задачу, обычно без связи с основным потоком, если связь необходима, то это делается HandlerилиBroadcastReceiver
  • Вызвать через Intent
  • Запущен из Main Thread
  • Работает в отдельном потоке
  • Невозможно запустить задачу параллельно, и несколько целей помещаются в очередь в одном рабочем потоке.
Уманг Котари
источник
19

Не изобретай велосипед

IntentService расширяет класс Service, что явно означает, что IntentServiceсделано специально для же цели.

Так в чем же цель?

`Цель IntentService - облегчить нашу работу для выполнения фоновых задач, даже не беспокоясь о

  • Создание рабочего потока

  • Очередь обработки нескольких запросов по одному (Threading )

  • Уничтожая Service

Таким образом, НЕТ , Serviceможет выполнить любую задачу, которая IntentServiceбудет делать. Если ваши требования подпадают под вышеупомянутые критерии, вам не нужно писать эту логику в Serviceклассе. Так что не изобретай велосипед, потому чтоIntentService это изобретенное колесо.

«Главное» отличие

Служба работает в потоке пользовательского интерфейса, а IntentService - в отдельном потоке.

Когда вы используете IntentService?

Если вы хотите выполнить несколько фоновых задач одну за другой, которая выходит за рамки действия, тогда IntentServiceвсе идеально.

Как IntentServiceсделано изService

Обычный сервис работает в потоке пользовательского интерфейса (любой тип компонента Android по умолчанию работает в потоке пользовательского интерфейса, например Activity:BroadcastReceiver , ContentProviderи Service). Если вам нужно выполнить какую-то работу, которая может занять некоторое время, то вы должны создать поток. В случае нескольких запросов вам придется иметь дело с synchronization. IntentServiceдается некоторая реализация по умолчанию, которая выполняет эти задачи за вас.
По словам разработчика

  1. IntentService создает рабочий поток

  2. IntentServiceсоздает рабочую очередь, которая отправляет запрос onHandleIntent()методу один за другим

  3. Когда нет работы, то IntentServiceвызывает stopSelf()метод
  4. Обеспечивает реализацию по умолчанию для onBind()метода, который является нулевым
  5. Реализация по умолчанию, для onStartCommand()которой отправляет Intentзапрос в WorkQueue и, в конце концов,onHandleIntent()
Рохит Сингх
источник
15

Добавление баллов к принятому ответу:

Смотрите использование IntentService в Android API. например:

public class SimpleWakefulService extends IntentService {
    public SimpleWakefulService() {
        super("SimpleWakefulService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {  ...}

Чтобы создать компонент IntentService для вашего приложения, определите класс, который расширяет IntentService, и в нем определите метод, который переопределяет onHandleIntent ().

Также см. Исходный код IntentService, его конструктор и методы жизненного цикла, такие как onStartCommand ...

  @Override
    public int More ...onStartCommand(Intent intent, int flags, int startId) {
       onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

Совместное использование AsyncTask является одним из лучших подходов для многих случаев, когда полезная нагрузка невелика. или просто создайте класс, расширяющий IntentSerivce. Начиная с версии 4.0 Android, все сетевые операции должны выполняться в фоновом режиме, иначе сборка / сборка приложения завершится неудачно. отдельный поток от пользовательского интерфейса. Класс AsyncTask предоставляет один из самых простых способов запуска новой задачи из потока пользовательского интерфейса. Более подробное обсуждение этой темы смотрите в блоге.

из руководства разработчика Android :

IntentService - это базовый класс для служб, которые обрабатывают асинхронные запросы (выраженные как Intents) по требованию. Клиенты отправляют запросы через вызовы startService (Intent); служба запускается по мере необходимости, обрабатывает каждое намерение, в свою очередь, используя рабочий поток, и останавливается, когда заканчивается его работа.

Шаблон проектирования, используемый в IntentService

: Этот шаблон «обработчик рабочей очереди» обычно используется для выгрузки задач из основного потока приложения. Класс IntentService существует, чтобы упростить этот шаблон и позаботиться о механике. Чтобы использовать его, расширьте IntentService и внедрите onHandleIntent (Intent). IntentService получит Intents, запустит рабочий поток и остановит службу соответствующим образом.

Все запросы обрабатываются в одном рабочем потоке - они могут занимать столько времени, сколько необходимо (и не будет блокировать основной цикл приложения), но одновременно обрабатывается только один запрос.

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

IntentService имеет несколько ограничений:

Он не может напрямую взаимодействовать с вашим пользовательским интерфейсом. Чтобы поместить его результаты в пользовательский интерфейс, вы должны отправить их в Activity. Рабочие запросы выполняются последовательно. Если операция выполняется в IntentService, и вы отправляете ему еще один запрос, запрос ожидает завершения первой операции. Операция, выполняемая на IntentService, не может быть прервана. Однако в большинстве случаев

IntentService является предпочтительным способом для простых фоновых операций

**

Библиотека залпа

Есть библиотека volley-library для разработки приложений для Android. . Исходный код доступен для всех на GitHub.

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

Шри Рама
источник
1
Было бы лучше, если бы вы могли дать краткий, точный ответ.
eRaisedToX
12

Я уверен, что вы можете найти обширный список различий, просто прибегая к помощи чего-то вроде «Android IntentService vs Service»

Одним из наиболее важных различий в каждом примере является то, что IntentService завершает себя, как только это будет сделано.

Некоторые примеры (быстро выдуманные) могут быть;

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

Сервис: Сервис, который будет постоянно использоваться для связи между вашим приложением и серверной частью с помощью вызовов веб-API. Даже если он закончил свою текущую задачу, вы все равно захотите, чтобы он был через несколько минут для большего общения.

Стефан де Брюйн
источник
2
Я не нашел ни одного примера, который можно было бы сделать с одним, а с другим. только некоторые объяснения, которые не помогли мне.
Ройберг
1
Попробуйте этот сайт, на нем есть много хороших объяснений основных концепций Android с приличными примерами vogella.com/articles/AndroidServices/article.html
Стефан де Брюйн
4
Это еще один пример "как использовать". не когда конкретно пользуюсь сервисом а когда интентсервисом. Пожалуйста, дайте мне теоретический пример, а не ссылки на «как использовать» или любые другие ссылки для этого метра. Я не прошу вас «работать» для меня, пока я ничего не делаю, просто я уже видел все эти симпатии и до сих пор не уверен.
Ройберг
5
это довольно важное различие. например, если вы используете службу для поддержания постоянного соединения с сервером, вы не можете использовать для этого intentservice, так как он завершается сразу после завершения всех своих задач
pelotasplus
24
когда я гуглю это, это приводит меня сюда. Теперь я нахожусь в бесконечном цикле.
Лу Морда
12

IntentService

IntentServiceработает в собственном потоке. Это остановится, когда это будет сделано. Больше похоже на огонь и забудь. Последующие звонки будут поставлены в очередь. Хорошо для очередей звонков. Вы также можете вращать несколько потоков внутри, IntentServiceесли вам нужно - вы можете добиться этого, используя ThreadPoolExecutor. Я говорю это потому, что многие люди спрашивают меня «зачем использовать, IntentServiceпоскольку он не поддерживает параллельное выполнение». IntentServiceэто просто нить. Вы можете делать все, что вам нужно, даже вращая несколько нитей. Единственное предостережение заключается в том, что он IntentServiceзаканчивается, как только вы вращаете эти несколько потоков. Это не ждет, когда эти темы вернутся. Вы должны позаботиться об этом. Поэтому я рекомендую использовать ThreadPoolExecutorв этих сценариях.

  • Хорошо для синхронизации, загрузки и т. Д.

обслуживание

По умолчанию Serviceработает в основном потоке. Вы должны крутить рабочий поток, чтобы сделать свою работу. Вы должны остановиться serviceявно. Я использовал это для ситуации, когда вам нужно запускать вещи в фоновом режиме, даже когда вы уходите от своего приложения и возвращаетесь больше для Headless service.

  • Опять же, вы можете запустить несколько потоков, если вам нужно.
  • Может использоваться для приложений, таких как музыкальные проигрыватели.

Вы всегда можете связаться с вашей деятельностью, используя, BroadcastReceiversесли вам нужно.

Сайой Валсан
источник
8

IntentService - это расширение службы, созданное для облегчения выполнения задачи, которая должна выполняться в фоновом режиме и в отдельном потоке.

IntentService запускается, создает поток и выполняет свою задачу в потоке. После того, как это сделано, он очищает все. Одновременно может работать только один экземпляр IntentService, несколько вызовов ставятся в очередь.

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

Например, сервис, подключенный к серверу xmpp и связанный действиями, нельзя просто сделать с помощью IntentService. В конечном итоге вы проигнорируете или переопределите материалы IntentService.

njzk2
источник
кажется, что большинство людей, которые хотят запустить действительно долго работающий сервис в фоновом режиме, в конечном итоге пытаются найти информацию об IntentService, потому что из-за документов создается впечатление, что это делается именно для этого, но в большинстве случаев вы также можете использовать новый поток. (новый Runnable ()). start (). другими словами, когда он говорит о том, что «порождает новый поток», и это все, что он делает, он не перемещает его в отдельный процесс, что, собственно, и делает большинство людей, когда они хотят отделить какой-то выполняемый код от действия. ! (потому что только порождение нитей - это один вкладыш)
Ласси Киннунен
intentService также заботится о жизненном цикле потока и использует петлитель, который помогает планировщику. Он также обеспечивает работу только одного экземпляра и ставит в очередь другие вызовы.
njzk2
5

Если кто-то может показать мне пример чего-то, что вы можете сделать с IntentServiceи не может быть сделано с serviceи наоборот.

IntentService не может использоваться для прослушивания в течение длительного времени, как и для прослушивателей XMPP, его единственный оператор времени, делает работу и машет на прощание.

Также у него есть только один многопоточник, но с хитростью вы можете использовать его как неограниченный.

user3764748
источник
4

Основное различие между a Serviceи a IntentServiceописывается следующим образом:

Обслуживание :

1.О Service по умолчанию запускается в главном потоке приложения (здесь рабочий поток по умолчанию недоступен). Таким образом, пользователь должен создать отдельный поток и выполнить необходимую работу в этом потоке.

2. Позволяет несколько запросов одновременно. (Многопоточность)

IntentService:

1. Теперь, перейдя к IntentService, здесь рабочий поток по умолчанию доступен для выполнения любой операции. Обратите внимание, что - Вам необходимо реализоватьonHandleIntent() метод, который получает намерение для каждого запроса на запуск, где вы можете выполнять фоновую работу.

2. Но это позволяет только один запрос за один раз.

Narendrakumar
источник
3

Android IntentService vs Сервис

1.Service

  • Служба вызывается с помощью startService ().
  • Сервис может быть вызван из любого потока.
  • Служба по умолчанию выполняет фоновые операции в главном потоке приложения. Следовательно, он может блокировать пользовательский интерфейс вашего приложения.
  • Служба, вызванная несколько раз, создаст несколько экземпляров.
  • Служба должна быть остановлена ​​с помощью stopSelf () или stopService ().
  • Сервис Android может запускать параллельные операции.

2. ИнтентСервис

  • IntentService вызывается с помощью Intent.
  • IntentService может вызываться только из основного потока.
  • IntentService создает отдельный рабочий поток для запуска фоновых операций.
  • IntentService, вызванный несколько раз, не создаст несколько экземпляров.
  • IntentService автоматически останавливается после завершения очереди. Нет необходимости вызывать stopService () или stopSelf ().
  • В IntentService несколько вызовов намерений автоматически ставятся в очередь, и они будут выполняться последовательно.
  • IntentService не может запускать параллельную операцию как служба.

См. Здесь

Дипак Гупта
источник