Планирование фоновых задач с помощью Jetpack WorkManager
Приложения Android могут работать в фоновом режиме разными способами, но иногда слишком большой выбор может быть плохим. Android имеет ряд API-интерфейсов и компонентов для планирования фоновой работы, и «правильный» подход может варьироваться в зависимости от версии Android и других факторов, таких как наличие у устройства доступа к сервисам Google Play.
Например, вы можете использовать JobScheduler для планирования фоновой работы, но только на Android 5.0 (API 21) и новее. Если вы хотите, чтобы ваше приложение было совместимо с более ранними версиями Android, вы можете использовать Firebase JobDispatcher, но есть одна загвоздка: для JobDispatcher требуются сервисы Google Play, и есть много пользователей Android, у которых нет доступа к сервисам Google Play, особенно в Китай.
WorkManager – это новая библиотека, которая значительно упрощает планирование и управление фоновой работой. Анонсированный на Google I / O 2018 как часть Jetpack, он предоставляет новый простой способ справляться с фоновыми задачами – делая всю тяжелую работу за вас.
Давайте посмотрим, как использовать WorkManager для планирования фоновой работы, параллельного выполнения задач и улучшения взаимодействия с пользователем, указав различные условия, которые необходимо выполнить перед запуском задачи.
Изучение Jetpack: что такое WorkManager?
WorkManager – это диспетчерская служба планирования задач, а затем забыть о них. После того, как задача будет запланирована, WorkManager запустит ее независимо от того, уйдет ли пользователь с соответствующего экрана, закроет приложение или даже перезагрузит свое устройство. Это делает его идеальным для задач, требующих гарантированного выполнения.
По умолчанию WorkManager запускает каждую задачу немедленно, но вы также можете указать условия, которые устройство должно выполнить перед запуском задачи, включая условия сети, состояние зарядки и объем доступного на устройстве дискового пространства. Например, вы можете уменьшить объем мобильных данных, потребляемых вашим приложением, отложив задачи с интенсивным использованием данных до тех пор, пока устройство не будет подключено к неизмеренной сети, или выполнять задачи, требующие интенсивного использования батареи, только во время зарядки устройства.
Если WorkManager выполняется во время работы вашего приложения, он будет выполнять свою работу в новом фоновом потоке. Если ваше приложение не запущено, WorkManager выберет наиболее подходящий способ планирования фоновой задачи в зависимости от таких факторов, как уровень API устройства и наличие у него доступа к сервисам Google Play. Таким образом, WorkManager может предоставлять функциональные возможности API-интерфейсов, таких как JobScheduler, без необходимости проверять возможности устройства и предоставлять альтернативные решения в зависимости от результатов. В частности, WorkManager использует JobScheduler на устройствах с API 23 и новее. В API 14-22 он будет использовать либо Firebase JobDispatcher, либо пользовательскую реализацию AlarmManager и BroadcastReceiver, если Firebase недоступна.
Поскольку WorkManager является частью Jetpack, он обратно совместим с API уровня 14, поэтому идеально подходит для планирования фоновых задач в более ранних версиях Android, где не поддерживаются такие решения, как JobScheduler. Он также может работать с сервисами Google Play или без них, поэтому вы можете быть уверены, что ваше приложение будет вести себя так, как ожидалось, даже в тех частях мира, где доступ к сервисам Google Play ограничен.
Когда WorkManager станет стабильным, он станет рекомендуемым планировщиком задач для задач, требующих гарантированного выполнения. WorkManager не предназначен для того, чтобы быть комплексным решением для каждой задачи, которую вам нужно запустить из основного потока, поэтому, если задача не требует гарантированного выполнения, вам следует вместо этого использовать службы намерений или службы переднего плана.
Одноразовая задача или повторяющаяся?
WorkManager поддерживает два типа работы:
OneTimeWorkRequest
Чтобы запланировать задачу, которая выполняется только один раз, вам необходимо создать объект OneTimeWorkRequest, а затем поставить задачу в очередь:
WorkManager workManager = WorkManager.getInstance();
workManager.enqueue(
Поскольку мы не указали никаких ограничений, эта задача будет запущена немедленно.
PeriodicWorkRequest
Вы захотите повторять некоторые задачи, например, синхронизировать данные вашего приложения с сервером один раз в день.
Чтобы создать повторяющуюся задачу, вы используете PeriodicWorkRequest.Builder для создания объекта PeriodicWorkRequest, указываете интервал между каждой задачей и затем ставите PeriodicWorkRequest в очередь. Здесь мы создаем задачу, которая будет запускаться каждые 12 часов:
new
Переход на WorkManager
Давайте посмотрим, как бы вы реализовали несколько различных рабочих процессов WorkManager, в том числе как создавать задачи, которые выполняются только при соблюдении определенных ограничений.
Я собираюсь создать приложение, состоящее из кнопки, которая будет передавать задачу WorkManager при нажатии. Чтобы не усложнять задачу, эта задача распечатает сообщение в Logcat Android Studio, но вы можете поменять части кода Logcat на любую другую задачу, которую вы имели в виду.
Создайте новый проект, затем откройте его файл build.gradle и добавьте библиотеку WorkManager в качестве зависимости проекта:
dependencies {
implementation fileTree(dir:
Создание макета вашего приложения
Затем создайте макет, состоящий из кнопки для запуска нашего потока WorkManager :
<?xml version="1.0" encoding="utf-8"?>
Создание одноразовых запросов на работу
В нашей MainActivity нам нужно выполнить следующее:
- Создайте экземпляр WorkManager, который будет отвечать за планирование задачи.
- Укажите класс Worker. Это класс, в котором вы определите задачу, которую должен выполнять WorkManager. Мы создадим этот класс на следующем шаге.
- Создайте WorkRequest. Вы можете использовать OneTimeWorkRequest.Builder или PeriodicWorkRequest.Builder. Я буду использовать OneTimeWorkRequest.Builder.
- Запланируйте WorkRequest, передав объект WorkRequest в WorkManager и указав любые ограничения, которым должно соответствовать устройство перед выполнением этой задачи.
Вот готовый класс MainActivity :
import
Какую задачу должен выполнять WorkManager?
Затем вам нужно указать задачу, которую WorkManager должен выполнять в фоновом режиме, расширив класс Worker и переопределив его метод doWork().
Чтобы создать этот рабочий класс:
- Перейдите в Файл> Создать> Класс Java.
- Назовите этот класс «MyWorker.java».
- Добавьте следующее:
import
Запустите свой проект на устройстве Android или виртуальном устройстве Android (AVD) и нажмите кнопку «Одноразовый запрос». Эта задача должна немедленно выполняться в фоновом режиме и выводить сообщение «doWork called» в Logcat Android Studio.
Установка некоторых ограничений: управление запуском задачи
По умолчанию WorkManager выполняет каждую задачу немедленно, но вы также можете указать ограничения, которые необходимо выполнить, прежде чем работа будет выполнена. Вы можете использовать его, чтобы отложить интенсивные задачи до тех пор, пока устройство не будет бездействовать, чтобы не повлиять на работу пользователя.
Чтобы установить некоторые правила о том, когда задача должна выполняться, вам необходимо создать объект Constraints с помощью Constraints.Builder, а затем указать ограничение (и), которое вы хотите использовать, например .setRequiresDeviceIdle :
Затем вам нужно передать объект Constraints в ваш WorkRequest :
.setConstraints(constraints())
WorkManager учтет эти ограничения, когда найдет идеальное время для выполнения вашей задачи.
Давайте обновим наш проект, чтобы сообщение выводилось в Logcat только тогда, когда устройство переходит в состояние низкого заряда батареи.
import
По возможности вам следует тестировать WorkManager на виртуальном устройстве Android (AVD), поскольку обычно легче моделировать различные состояния устройства, чем ждать, пока они естественным образом возникнут на вашем смартфоне или планшете.
Чтобы проверить ограничение батареи этого конкретного проекта, выполните следующие действия:
- Установите приложение на AVD.
- Щелкните значок «Дополнительно» в полосе элементов управления, которые появляются рядом с эмулятором (где находится курсор на следующем снимке экрана).
- В левом меню выберите «Батарея».
- Откройте раскрывающееся меню «Подключение зарядного устройства» и установите для него значение «Нет».
- Откройте раскрывающийся список «Состояние батареи» и установите для него значение «Не заряжается».
- Убедитесь, что «Уровень заряда» установлен на 100 процентов.
- Нажмите кнопку приложения «Одноразовый запрос».
- Проверьте окно Logcat в Android Studio; сообщение «doWork called» должно было быть напечатано как обычно.
Далее повторите этот процесс с низким уровнем заряда батареи:
- Еще раз щелкните значок «Еще», чтобы открыть окно «Расширенные элементы управления» Android Studio.
- В левом меню выберите «Батарея».
- Перетащите ползунок «Уровень заряда» до 15 процентов или ниже.
- Нажмите кнопку «Одноразовый запрос»; ничего не должно происходить.
- Перетащите ползунок на 100 процентов, и в Logcat должно появиться сообщение «doWork called».
Это также хорошая возможность увидеть, как WorkManager может запускать запланированные задачи, даже когда пользователь вышел из вашего приложения:
- Установите ползунок «Уровень заряда» AVD на 15 процентов.
- Нажмите кнопку «Одноразовый запрос»; никаких сообщений не должно появляться.
- Закройте ваше приложение.
- Увеличьте «Уровень заряда», и сообщение должно быть напечатано, даже если ваше приложение в настоящее время не отображается на экране.
Получите конкретность: установка нескольких ограничений
Иногда у вас есть задача, которая должна выполняться только при очень определенных обстоятельствах, например, вы можете отложить необычно интенсивную задачу до тех пор, пока устройство не зарядится, не подключится к Интернету и не простаивает.
Вы можете использовать WorkManager для построения цепочек ограничений. Здесь мы создаем задачу, которая будет выполняться только тогда, когда устройство подключено к неизмеренной сети и розетке:
import
Вы можете протестировать это приложение, выполнив только одно из этих ограничений и проверив, отображается ли сообщение в Logcat Android Studio:
- Установите обновленный проект на свой AVD.
- Нажмите кнопку «Еще», а затем «Батарея».
- В раскрывающемся списке выберите «Подключение зарядного устройства: зарядное устройство переменного тока» и «Состояние аккумулятора: зарядка».
- Отключите это эмулируемое устройство от Wi-Fi, открыв приложение настроек AVD, выбрав «Сеть и Интернет», а затем переместив ползунок Wi-Fi в положение «Выкл.».
- Вернитесь к своему приложению и нажмите кнопку «Одноразовый запрос». На этом этапе в Logcat ничего не должно отображаться, поскольку устройство успешно соответствует первому условию (зарядка), но не соответствует второму условию (подключено к сети).
- Вернитесь в меню «Настройки»> «Сеть и Интернет» на устройстве и переместите ползунок Wi-Fi в положение «Вкл.». Теперь, когда вы встретили оба ограничения, сообщение должно появиться на панели Logcat Android Studio.
Связь задач с WorkContinuation
Некоторые из ваших задач могут зависеть от успешного выполнения других задач. Возможно, вы захотите загрузить данные своего приложения на сервер, но только после того, как эти данные будут сжаты.
Вы можете создавать цепочки задач, вызывая метод beginWith () WorkManager и передавая ему первую задачу в цепочке. Это вернет объект WorkContinuation, который позволяет вам связывать последующие задачи с помощью метода WorkContinuation.then (). Наконец, при постановке этой последовательности в очередь с помощью WorkContinuation.enqueue () WorkManager выполнит все ваши задачи в запрошенном порядке.
Обратите внимание, что вы не можете ставить периодические и разовые работы в одну очередь.
Для создания цепочки нам понадобится второй класс Worker:
- Выберите Файл> Создать> Класс Java на панели инструментов Android Studio.
- Назовите этот класс «MySecondWorker».
- Введите следующий код:
import
Чтобы прояснить, какая задача выполняется, я собираюсь обновить класс MyWorker, чтобы он выводил в Logcat другое сообщение:
public
Затем добавьте в MainActivity следующее:
import
Нажмите кнопку приложения «Одноразовый запрос», и ваш вывод Logcat должен выглядеть примерно так:
D / MyWorker: Мой первый рабочий называется
D / WorkerWrapper: Результат рабочего УСПЕХ
D / WorkerWrapper: Установка статуса в очередь
D / MyWorker: Мой второй рабочий
D / WorkerWrapper: Результат рабочего УСПЕХ
В качестве альтернативы вы можете запускать эти задачи параллельно:
Если вам нужно создать более сложные последовательности, вы можете объединить несколько цепочек с помощью метода WorkContinuation.combine ().
Разные ограничения для разных задач
Вы можете комбинировать ограничения и связанные задачи, чтобы создать последовательность, в которой каждая задача ожидает выполнения различных наборов условий. Наше приложение может сжимать свои данные всякий раз, когда недостаточно места для хранения, а затем ждать, пока устройство не будет подключено к неизмеренной сети, прежде чем синхронизировать эти недавно сжатые данные с сервером.
Здесь я обновил свою MainActivity, так что request1 запускается только тогда, когда устройство заряжается, а request2 запускается только при наличии активного сетевого подключения:
import
Чтобы помочь нам увидеть, что происходит, я обновил сообщения MyWorker и MySecondWorker print до Logcat:
MyWorker:
MySecondWorker:
Подведение итогов
Вот как использовать новый WorkManager API для планирования фоновой работы, включая параллельное выполнение задач, создание цепочек связанных задач и использование ограничений, чтобы точно указать, когда задача должна выполняться.
Теперь, когда вы увидели WorkManager в действии, считаете ли вы, что это улучшение по сравнению с предыдущими планировщиками Android? Дайте нам знать в комментариях ниже!
Источник записи: https://www.androidauthority.com