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

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

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

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

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

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

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

Выберите подходящий вариант

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

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

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

Для каждого из этих сценариев есть свое дерево решений.

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

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

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

API для планирования задач

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

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

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

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

Активные службы

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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