Зареждане на данни, синхронизиране на съдържание, изпращане на анализи — много задачи не изискват активното участие на потребителя. Мобилните устройства обаче ограничават фоновата работа за пестене на батерия и поддържане на производителността. Фоновите задачи (background tasks) са механизми, които позволяват на приложението да изпълнява код, когато потребителят не го вижда. В тази статия ще разгледаме WorkManager, BGTaskScheduler, Foreground Service и особеностите на Doze Mode. Повече подробности в официалната документация на WorkManager.
Основни точки
Фонова задача е всеки код, който се изпълнява, когато приложението не е на преден план (активен екран). Това може да включва: периодична синхронизация на данни със сървъра, изтегляне на големи файлове, обработка на push известия, проследяване на геолокация, актуализиране на уиджети. Всяка платформа има свои ограничения за фонова работа: iOS е по-строг (10–30 минути фоново време), Android е по-щедър, но от версия 9 затегна правилата.
Архитектурата на фоновите задачи е изградена на три нива: (1) незабавни задачи — изпълняват се веднага (Foreground Service); (2) отложени задачи — изпълняват се при подходящи условия (WorkManager, BGTaskScheduler); (3) периодични задачи — повтарят се на зададен интервал. Правилният избор на ниво определя дали задачата ще бъде изпълнена навреме и дали ще доведе до отхвърляне на приложението от магазина.
И на двете платформи Google/Apple настоятелно препоръчват използването на декларативни API вместо директно управление на нишки във фонов режим. WorkManager на Android и BGTaskScheduler на iOS позволяват на системата оптимално да разпределя фоновата работа между приложенията, групирайки задачи за пестене на енергия. В IT Sectr винаги започваме проектирането на фоновата архитектура с анализ на изискванията за честота и спешност на актуализациите.
iOS предоставя няколко механизма за фонова работа. Background Fetch — периодично актуализиране на съдържанието с интервал, определен от системата (не от разработчика). Приложението получава прозорец от ~30 секунди за изтегляне на нови данни. Background Fetch се активира чрез Capabilities → Background Modes → Background Fetch и се имплементира в AppDelegate: application(_:performFetchWithCompletionHandler:).
BGTaskScheduler е модерното API за iOS 13+, което замества Background Fetch. Разработчикът регистрира задача с идентификатор, а системата я стартира при подходящи условия. BGAppRefreshTask — за кратки актуализации на съдържание; BGProcessingTask — за дълги задачи (почистване на кеш, синхронизация на база данни). Задачите се регистрират при стартиране на приложението, а системата планира тяхното изпълнение, като взема предвид състоянието на батерията, мрежата и активността на потребителя.
Background Modes — списък с режими, които позволяват фонова работа за конкретни сценарии: Audio (фоново възпроизвеждане), Location (GPS проследяване), VoIP (обаждания чрез PushKit), BLE (свързване с Bluetooth устройства), Processing (дълги задачи чрез BGTaskScheduler). Всеки режим изисква обосновка при преглед в App Store. Използването на режими без реална нужда е честа причина за отхвърляне на приложението.
Significant Location Change — механизъм за приложения, които не се нуждаят от постоянна геолокация, но трябва да знаят за значително придвижване на потребителя (над 500 метра). Системата събужда приложението при смяна на клетъчната кула. Този механизъм значително пести батерия в сравнение с постоянното GPS проследяване.
Android предлага най-богатия набор от API за фонови задачи, но от версия 8.0 (API 26) правилата станаха по-строги. WorkManager е препоръчителното решение от Google за всички видове фонови задачи. WorkManager гарантира изпълнение на задачата дори след рестартиране на устройството (чрез BootReceiver) и поддържа вериги от задачи, наблюдаеми LiveData/Flow и обратна съвместимост до API 14.
WorkManager използва Worker — базов клас с метод doWork(). Constraints определя условията за изпълнение: NetworkType.CONNECTED, BatteryNotLow, StorageNotLow. PeriodicWorkRequest — за периодични задачи с минимален интервал от 15 минути. WorkManager автоматично се адаптира към Doze Mode и App Standby, групирайки задачи в прозорци за поддръжка. Пример за прост Worker:
class SyncWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
val repository =
Injection.provideRepository(applicationContext)
repository.syncData()
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
// Запланировать задачу
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
val syncRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(constraints)
.build()
WorkManager.getInstance(context)
.enqueue(syncRequest)
JobScheduler — по-старо API (Android 5+, API 21). Планира задачи с посочени условия (мрежа, зареждане, неактивност). Ограничение: не поддържа рестартиране на устройството (изисква BootReceiver) и няма наблюдаемо състояние. JobScheduler е подходящ за прости задачи в наследени проекти; за нови проекти използвайте WorkManager.
Foreground Service — услуга, която потребителят вижда чрез постоянно известие (ongoing notification). Използва се за: възпроизвеждане на музика, GPS проследяване, изтегляне на големи файлове. Foreground Service има висок приоритет — системата няма да го убие при недостиг на памет. От Android 13 се изисква разрешение FOREGROUND_SERVICE_SPECIAL_USE за някои типове. Алтернатива е WorkManager с ForegroundServiceOption (дълги задачи).
AlarmManager — за задачи, които трябва да се изпълнят в точно определено време (будилник, напомняне). AlarmManager може да събуди устройството от Doze Mode (setAlarmClock). Не се препоръчва за редовна синхронизация поради висока консумация на енергия. За периодични задачи използвайте WorkManager, а AlarmManager само когато точното време е критично.
| Сценарий | iOS | Android |
|---|---|---|
| Периодично обновяване на съдържание | BGAppRefreshTask (BGTaskScheduler) | WorkManager (PeriodicWorkRequest) |
| Дълга фонова задача | BGProcessingTask | WorkManager + ForegroundService |
| Възпроизвеждане на аудио | Background Audio Mode | Foreground Service |
| GPS проследяване | Significant Location Change / Background Location | Foreground Service + FusedLocationProvider |
| VoIP / Обаждания | PushKit + CallKit | ConnectionService + Foreground Service |
| Точно време (будилник) | UNNotificationRequest (calendar) | AlarmManager |
| Обработка на push (фон) | Notification Service Extension | FirebaseMessagingService (onMessageReceived) |
Doze Mode е режим за пестене на енергия в Android, който влияе върху изпълнението на фонови задачи. Въведен в Android 6.0 (API 23). Когато устройството не се зарежда, екранът е изключен и устройството е неподвижно, Doze Mode блокира мрежови заявки, отлага JobScheduler и WakeLock. Периодично Doze отваря прозорци за поддръжка — кратки интервали, в които приложенията могат да изпълнят отложени задачи. От Android 7.0 (API 24) Doze се активира при изключен екран, а не само при пълна неподвижност.
App Standby — режим, при който неизползваните приложения се поставят в режим на изчакване. Ако дадено приложение няма активно известие и не е отваряно от няколко дни, то се поставя в Standby Bucket: активно (active), work, frequent, rare. Колкото по-рядко се използва приложението, толкова по-строги са ограниченията: мрежовите заявки се отлагат, синхронизацията се блокира, JobScheduler не се стартира.
WakeLock — механизъм, който поддържа устройството будно (предотвратява заспиването). Използва се за завършване на важни операции. WakeLock трябва да бъде освободен (release) след изпълнение на задачата, иначе батерията ще се изтощи за няколко часа. WakeLock не работи в Doze Mode — системата го игнорира. Работата с WakeLock на Android 8+ изисква разрешение WAKE_LOCK и правилно управление на жизнения цикъл.
В IT Sectr вземаме предвид Doze Mode и App Standby на етапа на проектиране. WorkManager автоматично обработва тези режими, но за Foreground Service трябва да се предвиди правилна обработка на преходите към Doze. Препоръчва се тестване на фонова работа на реални устройства с включен режим за пестене на енергия и след продължителни периоди на неактивност.
При проектиране на фонови задачи следвайте тези съвети. 1. Винаги използвайте WorkManager за нови Android проекти. Той решава проблеми със съвместимостта, Doze Mode и рестартиране на устройството. 2. На iOS предпочитайте BGTaskScheduler пред Background Fetch за iOS 13+. 3. Използвайте Foreground Service само когато задачата наистина изисква видимо известие. 4. Не злоупотребявайте с WakeLock — това изтощава батерията и може да доведе до отхвърляне на приложението. 5. Тествайте фонови задачи в Doze Mode: adb shell dumpsys deviceidle force-idle. 6. Винаги проверявайте изпълнението на задачата чрез логване и анализи. 7. Помнете лимитите: iOS дава ~30 секунди за Background Fetch и ~няколко минути за BGProcessingTask. Android WorkManager не гарантира точно време за изпълнение.
Често задавани въпроси
Background Service работи без видимо известие и може да бъде убит от системата по всяко време. Foreground Service трябва да показва постоянно известие (ongoing notification) и има по-висок приоритет. Foreground Service се използва за възпроизвеждане на музика и GPS проследяване.
Doze Mode е режим за пестене на енергия в Android, който изключва мрежовия достъп и отлага JobScheduler/WakeLock, когато устройството не се използва. WorkManager се адаптира към Doze Mode автоматично.
На iOS фоновите задачи се изпълняват чрез Background Fetch (периодични актуализации), BGTaskScheduler (отложени задачи) или Background Modes (аудио, VoIP, BLE, местоположение). BGTaskScheduler е модерното API за iOS 13+, което замества Background Fetch.
WorkManager е препоръчителното решение от Google за всички фонови задачи на Android. JobScheduler е по-старо API с ограничени възможности. WorkManager поддържа вериги от задачи, наблюдаеми LiveData/Flow и обратна съвместимост до API 14.
App Standby е режим на Android, при който неизползваните приложения се поставят в състояние на изчакване: мрежовите заявки се отлагат, синхронизацията се преустановява. Ако приложението не се използва няколко дни, Android го поставя в Standby Bucket (active, working, frequent, rare).
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.