Обзор фоновых задач

Приложениям часто приходится выполнять несколько задач одновременно. API-интерфейсы Android предоставляют множество различных способов сделать это. Выбор правильного варианта очень важен; вариант может быть правильным для одной ситуации, но совершенно неправильным для другой. Выбор неправильных API может снизить производительность вашего приложения или эффективность использования ресурсов, что может привести к разрядке аккумулятора и снижению производительности устройства пользователя в целом. В некоторых случаях выбор неправильного подхода может помешать вашему приложению появиться в Play Store.

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

Терминология

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

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

В этом документе мы будем использовать термин «задача» для обозначения операции, которую приложение выполняет вне основного рабочего процесса. Чтобы обеспечить согласованность в понимании, мы разбили это на три основные категории типов задач: асинхронная работа , API планирования задач и службы переднего плана .

Выберите правильный вариант

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

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

Для фоновых задач следует учитывать два основных сценария:

Эти два сценария имеют свои собственные деревья решений.

Асинхронная работа

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

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

API-интерфейсы планирования задач

API-интерфейсы планирования задач — более гибкий вариант, когда вам нужно выполнять задачи, которые необходимо продолжать, даже если пользователь покинет приложение. В большинстве случаев лучшим вариантом запуска фоновых задач является использование WorkManager , хотя в некоторых случаях может оказаться целесообразным использование API платформы JobScheduler .

WorkManager — мощная библиотека, позволяющая настраивать простые или сложные задания по мере необходимости. Вы можете использовать WorkManager, чтобы запланировать запуск задач в определенное время или указать условия, при которых задача должна выполняться. Вы даже можете настроить цепочки задач, чтобы каждая задача выполнялась по очереди, передавая свои результаты следующей. Чтобы понять все доступные параметры, прочтите список функций WorkManager .

Некоторые из наиболее распространенных сценариев для фоновых задач включают в себя:

  • Периодическое получение данных с сервера
  • Получение данных датчика (например, данных счетчика шагов)
  • Получение периодических данных о местоположении (вам должно быть предоставлено разрешение ACCESS_BACKGROUND_LOCATION на Android 10 или более поздней версии)
  • Загрузка контента на основе триггера контента, например фотографий, созданных камерой.

Службы переднего плана

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

Существует два метода создания службы переднего плана. Вы можете объявить свою собственную Service и указать, что эта служба является службой переднего плана, вызвав Service.startForeground() . Альтернативно вы можете использовать WorkManager для создания службы переднего плана, как описано в разделе о поддержке долго работающих рабочих процессов . Однако важно знать, что служба переднего плана, созданная WorkManager, должна подчиняться всем тем же ограничениям, что и любая другая служба переднего плана. WorkManager просто предоставляет некоторые удобные API, упрощающие создание службы переднего плана.

Альтернативные API

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

Некоторые из наиболее распространенных сценариев использования альтернативных API:

Задачи, инициированные пользователем

Блок-схема, показывающая, как выбрать подходящий API. В этой диаграмме обобщается материал раздела «Задачи, инициированные пользователем».
Рисунок 1. Как выбрать правильный API для запуска фоновой задачи, инициируемой пользователем.

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

Нужно ли продолжать выполнение задачи, пока приложение находится в фоновом режиме?

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

Будет ли неприятное впечатление от пользователя, если задача будет отложена или прервана?

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

Это короткая и важная задача?

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

Есть ли альтернативный API специально для этой цели?

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

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

Задачи в ответ на событие

Блок-схема, показывающая, как выбрать подходящий API. В этой таблице обобщается материал раздела «Задачи в ответ на событие».
Рисунок 2. Как выбрать правильный API для запуска фоновой задачи, запускаемой событием.

Иногда приложению необходимо выполнить фоновую работу в ответ на триггер, например:

Это может быть внешний триггер (например, сообщение FCM) или ответ на сигнал тревоги, установленный самим приложением. Например, игра может получить сообщение FCM, предлагающее обновить некоторые ресурсы.

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

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

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