Background: основы, работа приложения в фоне iOS и Android

Автор: IT Sectr Опубликовано: 2026-03-03 Время чтения: 10 мин

Background — состояние жизненного цикла приложения, в котором оно продолжает выполняться, но не отображается на экране. Объясняем основы фоновой работы на iOS и Android: ограничения, таймауты, фоновые задачи через beginBackgroundTask, WorkManager и Service, а также лучшие практики для корректной обработки Background.

Главное

  • Background — приложение не видимо пользователю, но может выполнять код в течение ограниченного времени
  • iOS background task — beginBackgroundTask(expirationHandler:) даёт до 30 секунд на завершение работы
  • Android Service — Foreground Service с уведомлением для долгих фоновых операций
  • WorkManager — рекомендуемый API для фоновых задач на Android с гарантией выполнения
  • Ограничения — обе платформы ужесточают правила фоновой работы для экономии батареи

Background — основы фонового состояния

Background — состояние приложения, в котором оно продолжает существовать в операционной системе, выполнять код и потреблять ресурсы, но не отображается на экране устройства. Пользователь находится на Home Screen, в другом приложении или экран устройства заблокирован. На iOS Background следует за Inactive — цепочка перехода: Active → Inactive → Background. На Android onStop сигнализирует о переходе Activity в Background.

Обе платформы накладывают строгие ограничения на фоновую работу. iOS предоставляет ограниченное окно (обычно 30 секунд) на выполнение кода после ухода в Background, после чего приложение переводится в Suspended. Android более гибок: Foreground Service с видимым уведомлением может работать неограниченно долго, но обычный Background Service ограничен несколькими минутами. Ключевая задача разработчика — корректно сохранить состояние и запланировать продолжение работы через системные API фоновых задач.

Система может завершить фоновое приложение в любой момент при нехватке памяти. При завершении все несохранённые данные теряются. Поэтому критически важно сохранять состояние в applicationDidEnterBackground (iOS) или onStop (Android). После завершения при следующем запуске приложение стартует из Not Running с холодным стартом и восстанавливает сохранённое состояние.

Background vs Suspended

Важно различать Background и Suspended. Background — приложение активно выполняет код. Suspended — приложение находится в памяти, но не выполняет код — оно заморожено. На iOS приложение переходит из Background в Suspended после завершения фоновых задач. На Android нет Suspended — процесс либо существует (включая Background), либо завершён (Not Running). Однако Android может приостановить выполнение потоков через LMK (Low Memory Killer).

ХарактеристикаiOS BackgroundAndroid Background
Код выполняетсяДа, до 30 секундДа, зависит от API
UI видимНетНет
Таймаут по умолчанию~30 сек (beginBackgroundTask)Несколько минут (Service)
Неограниченная работаТолько специальные категории (аудио, VoIP, навигация)Foreground Service с уведомлением
Гарантия выполненияНет — система может завершить в любой моментWorkManager гарантирует выполнение
Требуется разрешениеДа — capabilities в Info.plistДа — FOREGROUND_SERVICE пермишен
Следующее состояниеSuspended → Not RunningNot Running (или restart)

Background в iOS: Swift, beginBackgroundTask и BGTaskScheduler

В iOS Background обрабатывается через метод делегата applicationDidEnterBackground. В этом методе разработчик должен сохранить состояние пользователя, освободить ресурсы и завершить фоновые задачи. Для выполнения кода после ухода в Background используется beginBackgroundTask(expirationHandler:) — API, который запрашивает у системы дополнительное время (обычно 30 секунд). Если задача не завершается за это время, вызывается expirationHandler, и приложение принудительно переводится в Suspended.

С iOS 13 Apple представила BGTaskScheduler — современный API для планирования фоновых задач. В отличие от beginBackgroundTask, который даёт время только на завершение после ухода в фон, BGTaskScheduler позволяет запланировать выполнение задач в будущем — например, обновление контента раз в час или выгрузку аналитики ночью. BGTaskScheduler — рекомендуемый подход для новых проектов, так как он более эффективен с точки зрения батареи.

swift
import UIKit
import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    // Приложение ушло в фон — начинаем фоновую задачу
    func applicationDidEnterBackground(_ application: UIApplication) {
        saveAppState()
        startBackgroundTask()
    }

    private func startBackgroundTask() {
        backgroundTaskID = UIApplication.shared.beginBackgroundTask { [weak self] in
            // Время вышло — принудительно завершаем
            self?.endBackgroundTask()
        }

        // Симулируем фоновую работу (сохранение данных на сервер)
        DispatchQueue.global().async { [weak self] in
            uploadAnalyticsData()
            self?.endBackgroundTask()
        }
    }

    private func endBackgroundTask() {
        guard backgroundTaskID != .invalid else { return }
        UIApplication.shared.endBackgroundTask(backgroundTaskID)
        backgroundTaskID = .invalid
    }

    // Регистрация BGTaskScheduler
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: "com.example.refresh",
            using: nil
        ) { task in
            handleAppRefresh(task: task as! BGAppRefreshTask)
        }
        return true
    }

    func scheduleAppRefresh() {
        let request = BGAppRefreshTaskRequest(identifier: "com.example.refresh")
        request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
        try? BGTaskScheduler.shared.submit(request)
    }

    func handleAppRefresh(task: BGAppRefreshTask) {
        scheduleAppRefresh()
        task.expirationHandler = { task.setTaskCompleted(success: false) }
        fetchLatestData { result in
            task.setTaskCompleted(success: result)
        }
    }
}

В коде показана полная обработка Background на iOS. applicationDidEnterBackground запускает фоновую задачу через beginBackgroundTask с таймаутом и expirationHandler. Параллельно регистрируется BGTaskScheduler для периодического обновления контента. beginBackgroundTask используется для немедленного завершения работы, BGTaskScheduler — для долгосрочного планирования. Оба API требуют правильного управления идентификаторами задач.

Background в Android: Kotlin, Service, WorkManager

В Android Background управляется через несколько API. Традиционный Service позволяет выполнять код в фоне, но с Android 8+ (API 26) Background Service ограничен: система завершает его через несколько минут после ухода приложения в фон. Foreground Service с постоянным уведомлением может работать неограниченно долго. WorkManager — рекомендуемое решение для фоновых задач с гарантией выполнения даже после перезагрузки устройства.

Android, в отличие от iOS, поддерживает долгоживущие фоновые процессы. Foreground Service используется для задач, которые пользователь должен видеть — воспроизведение музыки, навигация, запись тренировки. JobScheduler и WorkManager — для задач, которые могут быть отложены: синхронизация данных, выгрузка логов, обновление кеша. Ключевое отличие: Android позволяет планировать задачи с условиями — Wi-Fi, зарядка, неактивность устройства, что экономит батарею и трафик.

kotlin
import android.app.Service
import android.content.Intent
import android.os.IBinder
import androidx.work.*

// 1. Foreground Service для долгой фоновой работы
class SyncService : Service() {

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notification = createNotification()
        startForeground(NOTIFICATION_ID, notification)
        performBackgroundWork()
        return START_STICKY
    }

    private fun performBackgroundWork() {
        Thread {
            // Синхронизация данных с сервером
            syncDataToServer()
            stopForeground(STOP_FOREGROUND_REMOVE)
            stopSelf()
        }.start()
    }

    override fun onBind(intent: Intent?): IBinder? = null
}

// 2. WorkManager для отложенных фоновых задач
class DataSyncWorker(
    private val context: Context,
    private val params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        return try {
            // Выгрузка аналитики на сервер
            uploadAnalytics()
            Result.success()
        } catch (e: Exception) {
            if (runAttemptCount < 3) Result.retry() else Result.failure()
        }
    }
}

// Планирование WorkManager задачи
fun scheduleBackgroundSync(context: Context) {
    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .setRequiresBatteryNotLow(true)
        .build()

    val request = OneTimeWorkRequestBuilder<DataSyncWorker>()
        .setConstraints(constraints)
        .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
        .build()

    WorkManager.getInstance(context).enqueue(request)
}

В коде показаны два подхода к фоновой работе на Android. SyncService — Foreground Service с уведомлением для немедленной и долгой фоновой работы. DataSyncWorker — WorkManager для отложенных задач с условиями (Wi-Fi, зарядка). WorkManager гарантирует выполнение даже при перезапуске устройства и поддерживает exponential backoff для повторных попыток. Foreground Service требует постоянного уведомления в статус-баре.

Ограничения фоновой работы на iOS и Android

Обе мобильные платформы постоянно ужесточают правила фоновой работы. На iOS каждое новое поколение ОС сокращает время работы в фоне и добавляет новые ограничения. На Android Google вводит всё более строгие режимы энергосбережения (Doze, App Standby). Разработчик должен быть в курсе актуальных ограничений, чтобы приложение не было завершено системой преждевременно.

На iOS, начиная с iOS 13, система отключает фоновые задачи для приложений, которые злоупотребляют фоновым временем. Каждое приложение получает определённые лимиты на основе поведения пользователя. BGTaskScheduler планирует выполнение на оптимальное время — например, когда устройство подключено к Wi-Fi и заряжается. Приложения, которые корректно используют BGTaskScheduler, получают больше фонового времени.

На Android начиная с Android 9 (API 28) фоновая работа ограничена режимом Doze, который активируется при бездействии устройства. Приложения в Doze не могут выполнять фоновые задачи, сеть отключается, JobScheduler и WorkManager откладывают задачи до выхода из Doze. Foreground Service — единственный способ обойти Doze, но злоупотребление приводит к блокировке приложения пользователем и удалению разрешений.

ОграничениеiOSAndroid
Таймаут фоновой задачи~30 секунд (beginBackgroundTask)Несколько минут (JobScheduler)
Неограниченный фонАудио, VoIP, навигация, BluetoothForeground Service + уведомление
ЭнергосбережениеLow Power Mode — отключает фоновые задачиDoze, App Standby, Battery Optimization
ПланированиеBGTaskScheduler (iOS 13+)WorkManager (Android Jetpack)
После перезагрузкиТолько push-уведомлениеWorkManager сохраняет задачи
Макс. время выполнения~30 минут (аудио)Неограниченно (Foreground Service)

Лучшие практики фоновой работы

Первое правило — минимизируйте потребление ресурсов в фоне. Большинство фоновых задач можно отложить на время, когда устройство заряжается и подключено к Wi-Fi. Используйте BGTaskScheduler (iOS) и WorkManager (Android) для планирования задач с условиями. Не запускайте тяжёлые вычисления в фоне — это разряжает батарею и приводит к троттлингу CPU.

Второе правило — всегда указывайте expirationHandler для beginBackgroundTask. Если приложение не завершит задачу в отведённое время, система принудительно переведёт его в Suspended или завершит. ExpirationHandler — последний шанс сохранить данные и корректно завершить работу. На Android используйте setForegroundAsync в WorkManager для преобразования обычной задачи в foreground, если требуется больше времени.

Третье правило — проверяйте ограничения фоновой работы перед запуском. На iOS используйте UIApplication.shared.backgroundTimeRemaining для проверки оставшегося времени. На Android проверьте ActivityManager.isBackgroundRestricted() — если true, приложение не сможет запускать фоновые задачи, и нужно предложить пользователю снять ограничения в настройках. Это особенно важно для приложений с критическими фоновыми функциями — будильники, календари, синхронизация.

Четвёртое правило — тестируйте фоновые задачи на реальном устройстве. Симулятор и эмулятор не воспроизводят реальные ограничения фоновой работы. На iOS используйте Debug → Simulate Background Fetch в Xcode. На Android — adb shell am broadcast -a android.intent.action.ACTION_BOOT_COMPLETED для тестирования WorkManager после перезагрузки. Реальные тесты на устройстве с низким зарядом батареи выявляют большинство проблем фоновой работы.

swift
import UIKit

final class BackgroundTaskManager {
    static let shared = BackgroundTaskManager()
    private var tasks: [String: UIBackgroundTaskIdentifier] = [:]

    func startTask(name: String, expiration: @escaping () -> Void) {
        let remaining = UIApplication.shared.backgroundTimeRemaining
        print("Осталось времени в фоне: \(remaining) сек")

        let task = UIApplication.shared.beginBackgroundTask { [weak self] in
            print("Истекло время для задачи: \(name)")
            expiration()
            self?.endTask(name: name)
        }

        tasks[name] = task
    }

    func endTask(name: String) {
        guard let task = tasks.removeValue(forKey: name),
              task != .invalid
        else { return }
        UIApplication.shared.endBackgroundTask(task)
    }
}

В коде показан менеджер фоновых задач, который отслеживает оставшееся время и управляет идентификаторами. backgroundTimeRemaining возвращает количество секунд до принудительного завершения — если значение бесконечно, приложение работает без ограничения (аудио, навигация). Менеджер позволяет запускать несколько фоновых задач с разными именами и корректно завершать каждую. Такой подход предотвращает утечку фоновых задач и гарантирует, что система не завершит приложение из-за незакрытых задач.

Часто задаваемые вопросы

Может ли iOS приложение работать в фоне вечно?

Да, для ограниченного числа категорий: аудио (AVAudioSession категория .playback), VoIP (PushKit), навигация (CLLocationManager с allowsBackgroundLocationUpdates), Bluetooth (central background mode), фоновое обновление (BGTaskScheduler). Для всех остальных — максимум 30 секунд. В iOS 16+ Apple ужесточила требования даже для разрешённых категорий.

Чем beginBackgroundTask отличается от BGTaskScheduler?

beginBackgroundTask — синхронный API для продления жизни приложения на ~30 секунд после ухода в фон. Вызывается в applicationDidEnterBackground. BGTaskScheduler — асинхронный API для планирования задач в будущем через системные триггеры (время, местоположение, обновление контента). BGTaskScheduler — современный подход, рекомендуемый Apple для iOS 13+.

Почему Android убивает мой Background Service?

Начиная с Android 8 (API 26), Background Service завершается через несколько минут после ухода приложения в фон. Решение: используйте Foreground Service с уведомлением для долгих операций или WorkManager для отложенных задач. Проверьте Battery Optimization для вашего приложения в настройках — если оно оптимизировано, система может отложить или отменить фоновые задачи.

Как протестировать Background на симуляторе iOS?

Нажмите Cmd+Shift+H для перехода на Home Screen. В Xcode используйте Debug → Simulate Background Fetch. Для проверки beginBackgroundTask откройте консоль (Shift+Cmd+C) и вызовите e UIApplication.shared.backgroundTimeRemaining. В Xcode 15+ доступен Background Execution сценарий в Diagnostics tab симулятора.

Что такое process death на Android?

Process Death — завершение процесса Android системой при нехватке ресурсов или при простое в фоне. В отличие от iOS, Android не имеет Suspended — процесс либо жив (может быть в фоне), либо мёртв (Not Running). Process Death — нормальное поведение ОС, и приложение должно корректно восстанавливать состояние после него через SavedStateHandle, onSaveInstanceState или DataStore.

Итоги

  • Background — приложение не видимо на экране, но выполняет код, в отличие от Suspended (заморожено)
  • iOS — beginBackgroundTask (до 30 сек) и BGTaskScheduler для планирования будущих задач
  • Android — Foreground Service для долгих операций, WorkManager для отложенных задач с гарантией
  • Ограничения — обе платформы ужесточают правила фоновой работы: Doze, Low Power Mode, App Standby
  • Сохранение — applicationDidEnterBackground и onStop — последний шанс сохранить данные перед Suspended/Not Running
  • Планирование — BGTaskScheduler и WorkManager работают с условиями (Wi-Fi, зарядка, время)
  • Foreground Service — единственный способ неограниченной фоновой работы на обеих платформах

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

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

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