Создание служб Android

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

Обзор служб Android

Мобильные приложения не похожи на классические приложения. Настольные компьютеры имеют достаточное количество ресурсов, таких как недвижимость экрана, память, место хранения и подключенный источник питания, мобильные устройства не делают. Эти ограничения позволяют мобильным приложениям вести себя по-разному. Например, небольшой экран на мобильном устройстве обычно означает, что одновременно отображается только одно приложение (т. е. действие). Другие действия перемещаются в фон и отправляются в приостановленное состояние, в котором они не могут выполнять какие-либо действия. Однако только потому, что приложение Android находится в фоновом режиме, не означает, что невозможно продолжать работу приложения.

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

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

Службы и их способность выполнять фоновую работу имеют решающее значение для обеспечения плавного и гибкого пользовательского интерфейса. Все приложения Android имеют основной поток (также известный как поток пользовательского интерфейса), в котором выполняются действия. Чтобы устройство было адаптивно, Android должен иметь возможность обновлять пользовательский интерфейс с частотой 60 кадров в секунду. Если приложение Android выполняет слишком много работы с основным потоком, Android удаляет кадры, что, в свою очередь, приводит к тому, что пользовательский интерфейс будет отображаться рывком (также иногда называется janky). Это означает, что любая работа, выполняемая в потоке пользовательского интерфейса, должна выполняться в интервале времени между двумя кадрами, примерно 16 миллисекунд (1 секунда каждые 60 кадров).

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

When device rotates, instance 1 is destroyed and instance 2 is created

Это потенциальная утечка памяти— поток, созданный первым экземпляром действия, по-прежнему будет выполняться. Если в потоке есть ссылка на первый экземпляр действия, это предотвратит сборку мусора Android. Однако второй экземпляр действия по-прежнему создается (который, в свою очередь, может создать новый поток). Смена устройства несколько раз в быстром последовательности может исчерпать все ОЗУ и принудительно завершить работу всего приложения для восстановления памяти.

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

Фоновая работа может быть разделена на две широкие классификации:

  1. Долго выполняющаяся задача — это работа, которая продолжается до явной остановки. Пример длительной задачи — это приложение, которое передает музыку или должно отслеживать данные, собранные датчиком. Эти задачи должны выполняться, даже если приложение не имеет видимого пользовательского интерфейса.
  2. Периодические задачи — (иногда называются заданием) Периодическая задача — это задача, которая является относительно короткой длительностью (несколько секунд) и выполняется по расписанию (т. е. один раз в неделю или, возможно, всего один раз в ближайшие 60 секунд). Примером этого является скачивание файла из Интернета или создание эскиза для изображения.

Существует четыре различных типа служб Android:

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

  • IntentService — Специализированный IntentService подкласс Service класса, упрощающий создание и использование служб. Предназначено IntentService для обработки отдельных автономных вызовов. В отличие от службы, которая может одновременно обрабатывать несколько вызовов, более похожа на рабочий обработчик очереди— IntentService работа выполняется в очереди и IntentService обрабатывает каждое задание одновременно в одном рабочем потоке. Как правило, неIntentService привязан к активности или фрагменту.

  • Запущенная служба — запущенная служба — это служба , которая была запущена некоторыми другими компонентами Android (например, действием) и выполняется непрерывно в фоновом режиме, пока не будет явно указано, что служба остановится. В отличие от связанной службы, запущенная служба не связана с ней напрямую. По этой причине важно разработать запущенные службы, чтобы они могли быть корректно перезапущены по мере необходимости.

  • Гибридная службаэто служба, которая имеет характеристики запущенной службы и привязанной службы. Гибридная служба может быть запущена, когда компонент привязывается к нему или может быть запущен некоторым событием. Клиентский компонент может быть привязан или не привязан к гибридной службе. Гибридная служба будет работать до тех пор, пока она явно не будет остановлена или пока к ней больше не привязаны клиенты.

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

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

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

Ограничения фонового выполнения в Android 8.0

Начиная с Android 8.0 (уровень API 26), приложение Android больше не может работать свободно в фоновом режиме. Когда на переднем плане приложение может запускать и запускать службы без ограничений. При переходе приложения в фоновом режиме Android предоставит приложению определенное время для запуска и использования служб. Когда это время истекло, приложение больше не может запускать какие-либо службы и все запущенные службы будут прекращены. На этом этапе приложению не удается выполнить любую работу. Android считает приложение на переднем плане, если выполняются одно из следующих условий:

  • Существует видимое действие (запущено или приостановлено).
  • Приложение запустило службу переднего плана.
  • Другое приложение находится на переднем плане и использует компоненты из приложения, которое будет в противном случае в фоновом режиме. Примером этого является то, что приложение A, которое находится на переднем плане, привязано к службе, предоставленной приложением B. Приложение B. Затем также будет рассматриваться на переднем плане и не завершается Android для того, чтобы находиться в фоновом режиме.

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

  • Приложение получает высокоприоритетное облачное сообщение Firebase.
  • Приложение получает трансляцию.
  • Приложение получает и выполняет PendingIntent ответ на уведомление.

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

  • Планирование работы в фоновом режиме с помощью планировщика заданий Android или диспетчера заданий Firebase. Эти две библиотеки предоставляют платформу для приложений для разделения фоновой работы в заданиях, дискретной единицы работы. Затем приложения могут запланировать задание с операционной системой вместе с некоторыми критериями о том, когда задание может выполняться.
  • Запустите службу на переднем плане — служба переднего плана полезна, когда приложение должно выполнять некоторые задачи в фоновом режиме, и пользователю может потребоваться периодически взаимодействовать с этой задачей. Служба переднего плана будет отображать постоянное уведомление, чтобы пользователь знал, что приложение выполняет фоновую задачу, а также предоставляет способ мониторинга или взаимодействия с задачей. Примером этого будет приложение podcasting, которое играет подкаст пользователю или, возможно, скачивание эпизода podcast, чтобы его можно было наслаждаться позже.
  • Используйте высокоприоритетное облачное сообщение Firebase (FCM) — когда Android получает высокоприоритетное FCM для приложения, оно позволит приложению запускать службы в фоновом режиме в течение короткого периода времени. Это была бы хорошая альтернатива наличии фоновой службы, которая опрашивает приложение в фоновом режиме.
  • Отложите работу при переходе приложения на передний план . Если ни одно из предыдущих решений жизнеспособно, приложения должны разрабатывать собственный способ приостановки и возобновления работы, когда приложение переходит на передний план.