Здравствуйте друзья,

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

  1. Компонент приложения, который используется для выполнения длительных фоновых операций.
  2. Сервис не имеет пользовательского интерфейса.
  3. Служба может продолжать работать даже после того, как пользователь переключится на другое приложение.
  4. Компонент может привязываться к службе, выполнять взаимодействия и выполнять IPC (межпроцессное взаимодействие).

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

Что может сделать служба?

Все нижеперечисленные операции могут выполняться Сервисом из фона:

  • Он может обрабатывать сетевые транзакции,
  • Воспроизводить музыку
  • Выполнить файловый ввод-вывод
  • Взаимодействие с контент-провайдером приложения

Изучение типов услуг

Существует 3 различных типа услуг:

  1. Фоновая служба
  2. Служба переднего плана
  3. Связанная служба

Фоновая служба: используется для выполнения операции, которая обычно не замечается пользователем.

  • Например, сжатие хранилища устройства.

Примечание. Если ваше приложение нацелено на уровень API 26 или выше, система накладывает ограничения на запуск фоновых служб, когда само приложение не находится на переднем плане. Например, в большинстве ситуаций нам не следует получать доступ к информации о местоположении из фона. Вместо этого планируйте задачи с помощью WorkManager.

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

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

Примечание. API WorkManager предлагает гибкий способ планирования задач и при необходимости может запускать эти задачи как службы переднего плана. Во многих случаях использование WorkManager предпочтительнее прямого использования служб переднего плана.

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

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

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

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

onStartCommand(), чтобы позволить компонентам запускать его и

onBind(), чтобы разрешить привязку.

Обратите внимание, что :

Значение по умолчанию зависит от того, содержит ли служба фильтры намерений. Отсутствие каких-либо фильтров означает, что его можно вызвать, только указав точное имя класса. Это означает, что служба предназначена только для внутреннего использования приложения (поскольку другие не будут знать имя класса). Таким образом, в этом случае значение по умолчанию — «false».

С другой стороны, наличие хотя бы одного фильтра подразумевает, что сервис предназначен для внешнего использования, поэтому значение по умолчанию — «true».

Определение службы

Здесь мы объявили MyAppService как запись xml ‹service /› в android_manifest.xml.

Мы можем гарантировать, что наш сервис доступен только нашему приложению, включив атрибут android:exported и установив для него значение false. Это эффективно предотвращает запуск вашей службы другими приложениями, даже если используется явное намерение.

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

onStartCommand()

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

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

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

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

onBind()

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

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

Мы должны всегда применять этот метод; однако, если мы не хотим разрешать привязку, мы должны вернуть значение null.

onCreate()

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

Если служба уже запущена, этот метод не вызывается.

onDestroy()

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

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

Это последний звонок, который получает служба.

Реализуя эти методы, вы можете отслеживать эти два вложенных цикла жизненного цикла службы:

  • Все время жизни службы происходит между моментом вызова onCreate() и временем возврата onDestroy().
  • Подобно действию, служба выполняет начальную настройку в onCreate() и освобождает все оставшиеся ресурсы в onDestroy().
  • Например, служба воспроизведения музыки может создать поток, в котором музыка воспроизводится в onCreate(), а затем остановить поток в onDestroy().

Примечание. Методы onCreate() и onDestroy() вызываются для всех служб, независимо от того, созданы ли они startService() или bindService().

  • Активное время жизни службы начинается с вызова либо onStartCommand(), либо onBind(). Каждому методу передается Intent, который был передан либо startService(), либо bindService().
  • Если служба запущена, активное время жизни заканчивается одновременно с окончанием всего времени жизни (служба все еще активна даже после возврата onStartCommand()). Если служба привязана, активное время жизни заканчивается, когда возвращается onUnbind().

Примечание. Хотя запущенная служба останавливается вызовом либо stopSelf(), либо stopService(), для службы нет соответствующего обратного вызова (нет обратного вызова onStop()). Если служба не привязана к клиенту, система уничтожает ее при остановке службы — onDestroy() — единственный полученный обратный вызов.

Запущенная служба: ее можно определить как службу, которая была запущена компонентом путем вызова startService(), что приводит к вызову метода службы onStartCommand().

  • Жизненный цикл запущенной службы не зависит от компонента, который ее запускает.
  • Служба должна остановить себя, когда ее работа будет завершена, вызвав stopSelf(), или другой компонент может остановить ее, вызвав stopService().
  • Если действие запускает службу, оно передает необходимые параметры службе через метод anIntent.. То же самое намерение получает служба в методе onStartCommand().

Вот весь жизненный цикл обратных вызовов сервиса. На нем изображены 2 типа или услуги:

  • Связанный сервис
  • Свободный сервис

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

Служба, изначально запущенная с onStartCommand() (клиентом, вызывающим startService()), все еще может принимать вызов onBind() (когда клиент вызывает bindService()).

Вот и все, спасибо, что читаете.

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