У меня есть задача запустить несколько разных заданий в приложении для Android. Каждое задание является длительным и сильно потребляет сеть, базу данных и файловую систему. Каждое задание может запускаться пользователем вручную или по расписанию с помощью AlarmManager. Очень важно, чтобы каждое задание выполнялось до конца, поэтому оно должно продолжать выполняться после того, как пользователь покинет приложение или даже когда пользователь вообще не открывает приложение. Задания имеют некоторый атрибут ID, например:
class Job {
int id;
}
Мне нужен этот гипотетический JobManager, чтобы получать задания и сортировать их по ID. Если задание с id = 1 уже выполняется, то JobManager должен пропустить все последующие задания с id = 1, пока это задание не будет завершено. Но если задание отправляется с id = 2, то оно принимается и может выполняться параллельно с первым заданием.
Задания также должны сохранять блокировку пробуждения до завершения, как это делается в WakefulIntentService CommonsWare.
У меня есть несколько идей, как это реализовать, но у всех есть свои недостатки:
- Подкласс класса Service, который всегда работает в фоновом режиме и автоматически перезапускается, если по какой-либо причине его уничтожают. Недостатки: он потребляет ресурсы, даже если ничего не запускает, он работает в потоке пользовательского интерфейса, поэтому нам приходится управлять некоторыми потоками, которые могут быть уничтожены системой, как обычно, каждый клиент должен запускать Сервис, и никто не знает, когда его остановить.
- WakefulIntentService от CommonsWare. Недостатки: поскольку это IntentService, он запускается только последовательно, поэтому не может проверить наличие уже запущенного задания.
- Булев флаг «работает» в базе данных для каждого задания. Проверяйте его каждый раз, когда мы хотим запустить задание. Недостатки: слишком много запросов к БД, сложно реализовать правильно, иногда 2 одинаковых задания все еще могут выполняться параллельно, не уверен, что флаги останутся «истинными» в случае какой-либо неожиданной ошибки.
Существующая библиотека предназначена для этой цели. На данный момент кроме CWAC-Wakeful я нашел:
- Robospice: https://github.com/stephanenicolas/robospice
- Очередь заданий Android: https://github.com/path/android-priority-jobqueue
но все же я не знаю, как использовать эти библиотеки для запуска ровно одной централизованной службы, которая будет принимать задания от любых других действий, служб, BroadcastReceiver, AlarmManager и т. д., сортировать их по идентификатору и запускать параллельно.
Посоветуйте, какое решение можно использовать в этом случае.
ОБНОВЛЕНИЕ: см. ниже мое собственное решение. Я не уверен, работает ли это во всех возможных случаях. Если вы знаете о каких-либо проблемах, которые могут возникнуть с этим, пожалуйста, прокомментируйте.