Перейти к содержанию
Innovialabs

Фоновые задачи в iOS и Android: ограничения и надёжные подходы

Продвинутое3 мин

Коротко

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

Главное: фон не гарантирован

И iOS, и Android экономят батарею и поэтому сами решают, когда и сколько приложению работать в фоне. Нельзя рассчитывать, что код выполнится «каждые 15 минут» или «ровно в 9:00». Надёжный подход — относиться к фону как к бонусу:

  • ставить задачи через системные планировщики (WorkManager, BGTaskScheduler);
  • для передачи файлов использовать фоновые сетевые сессии, которые ведёт сама ОС;
  • делать операции идемпотентными и уметь продолжать с места обрыва;
  • всегда досинхронизироваться при открытии приложения.

Ограничения Android

  • Doze — при неподвижном устройстве с выключенным экраном система откладывает сетевой доступ, будильники и задачи до коротких окон обслуживания.
  • App Standby Buckets — чем реже пользователь открывает приложение, тем реже ему разрешают работать в фоне.
  • Ограничения на запуск сервисов из фона — обычный фоновый Service надолго не живёт; для долгой видимой пользователю работы нужен foreground service с уведомлением и объявленным типом.
  • Оболочки производителей — у ряда OEM есть собственные агрессивные «оптимизаторы батареи», которые убивают процессы сильнее, чем стандартный Android. На таких устройствах приходится просить пользователя добавить приложение в исключения.

Ограничения iOS

  • После ухода в фон приложение быстро приостанавливается. Короткую задачу можно завершить, запросив дополнительное время, но это минуты, а не часы.
  • BGTaskScheduler запускает BGAppRefreshTask (короткое обновление) и BGProcessingTask (долгая работа, часто на зарядке). Время запуска выбирает система с учётом того, как часто пользователь открывает приложение.
  • Silent push (content-available) может разбудить приложение, но доставка не гарантируется и ограничивается системой.
  • Если пользователь принудительно закрыл приложение свайпом, большинство фоновых механизмов перестаёт его будить.

Какой инструмент для какой задачи

ЗадачаAndroidiOS
Периодическая синхронизацияWorkManager, PeriodicWorkRequestBGAppRefreshTask
Тяжёлая обработка, бэкапWorkManager с ограничениями (зарядка, Wi-Fi)BGProcessingTask
Загрузка и выгрузка файловWorkManager, при необходимости foreground serviceBackground URLSession
Срочное событие с сервераPush-уведомление (FCM)Push-уведомление (APNs)
Трекинг маршрута, навигацияForeground service с типом locationBackground location mode
Обновление по геозонамGeofencing APIRegion monitoring, significant location changes

WorkManager на практике

WorkManager переживает перезагрузку устройства и сам выбирает подходящий механизм под капотом:

val request = PeriodicWorkRequestBuilder<SyncWorker>(1, TimeUnit.HOURS)
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.CONNECTED)
            .build()
    )
    .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
    .build()

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "sync", ExistingPeriodicWorkPolicy.KEEP, request
)

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

Фоновая геолокация и загрузки

  • Геолокация в фоне требует отдельного разрешения, понятного объяснения пользователю и обоснования при ревью в сторах. Используйте минимально достаточную точность: значимые изменения местоположения и геозоны расходуют батарею заметно меньше, чем постоянный GPS.
  • Загрузки больших файлов отдавайте системе: на iOS — background URLSession, которая продолжит передачу даже при приостановленном приложении; на Android — WorkManager с поддержкой докачки. Сервер должен поддерживать возобновляемую загрузку по частям.

Паттерны надёжной синхронизации

  1. Локальная очередь операций. Действия пользователя сначала пишутся в базу на устройстве, затем отправляются.
  2. Идемпотентность. У каждой операции есть уникальный ключ, и повторная отправка не создаёт дубль на сервере.
  3. Инкрементальная синхронизация по курсору или метке времени вместо полной перезагрузки данных.
  4. Ретраи с экспоненциальной задержкой и учётом состояния сети.
  5. Push как сигнал, а не как данные: уведомление говорит «есть изменения», а данные приложение забирает само.
  6. Синхронизация при открытии как обязательная страховка.
  7. Мониторинг: логируйте, когда задачи реально выполнялись, чтобы видеть проблемы на конкретных устройствах.

Частые вопросы

Надёжно — нет. Для напоминаний пользователю используйте локальные уведомления, а данные синхронизируйте при ближайшей возможности, которую даст система.

Поможем с этим

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

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.