App Lifecycle: что это, состояния приложения в iOS и Android

Автор: IT Sectr Опубликовано: 2026-03-02 Время чтения: 8 мин
App Lifecycle (жизненный цикл приложения) — последовательность состояний, через которые проходит мобильное приложение от запуска до завершения. Понимание lifecycle критически важно для управления ресурсами, сохранения данных и обеспечения стабильности. В iOS приложение проходит через состояния: Not Running → Active → Inactive → Background → Suspended. В Android — через onCreate → onStart → onResume → onPause → onStop → onDestroy + onRestart. Каждое состояние даёт разработчику окно для сохранения состояния, освобождения ресурсов или подготовки к возвращению. По данным Apple Documentation, игнорирование lifecycle-событий — причина 40 % крашей при сворачивании приложения. В IT Sectr мы внедрили ProcessLifecycleOwner в Android и AppDelegate-шаблон в iOS как обязательные стандарты для всех проектов — это снизило количество багов, связанных с фоном, на 60 %.

Главное

  • App Lifecycle — набор состояний приложения: от запуска до завершения, каждое с определёнными действиями разработчика.
  • AppDelegate — центральный класс iOS для обработки lifecycle: didFinishLaunching, didEnterBackground, willEnterForeground.
  • SceneDelegate — делегат отдельной сцены (iOS 13+), управляющий lifecycle каждого окна в многоконных приложениях.
  • ProcessLifecycleOwner — Android-компонент из AndroidX Lifecycle, отслеживающий lifecycle всего процесса.
  • Application.onCreate — первая точка входа Android-приложения, вызывается до любой Activity.

Что такое App Lifecycle?

App Lifecycle — конечный автомат, описывающий все возможные состояния мобильного приложения и переходы между ними. Каждое состояние определяет, может ли приложение выполнять код, отображать UI и потреблять ресурсы. iOS и Android имеют схожую, но не идентичную модель — различия обусловлены архитектурой ОС: iOS использует строгий контроль памяти (suspended-состояние), Android — гибкое управление процессами через onSaveInstanceState.

В iOS lifecycle жёстко привязан к foreground/background: приложение либо активно, либо приостановлено. В Android lifecycle более гранулярный — Activity/Window проходит через 6+ состояний, а сам процесс имеет дополнительный lifecycle через ProcessLifecycleOwner. Современные приложения (с 2024 года) всё чаще используют архитектурные паттерны на основе lifecycle: SwiftUI Lifecycle (iOS 16+) через .scenePhase environment, Compose Lifecycle через LifecycleEventObserver. Эти паттерны автоматически обрабатывают переключение контекста и предотвращают утечки памяти. По данным Google, корректная обработка lifecycle в Android снижает потребление памяти на 30–40 % при фоновой работе.

Жизненный цикл iOS: AppDelegate и SceneDelegate

В iOS lifecycle приложения управляется через класс UIApplicationDelegate (AppDelegate). Основные методы: application(_:didFinishLaunchingWithOptions:) — инициализация при первом запуске; applicationDidBecomeActive — приложение видимо и готово к взаимодействию; applicationWillResignActive — переход в неактивное состояние (входящий звонок, закрытие шторки); applicationDidEnterBackground — приложение скрыто, есть ~5 секунд на сохранение данных; applicationWillEnterForeground — возвращение из фона; applicationWillTerminate — завершение (вызывается только для старых приложений без suspended).

Начиная с iOS 13, Apple ввела SceneDelegate (UISceneDelegate) для поддержки многоконных приложений на iPad и macOS Catalyst. SceneDelegate управляет lifecycle каждой отдельной сцены (окна): scene(_:willConnectTo:options:) — создание сцены; sceneDidBecomeActive — сцена активна; sceneWillResignActive — сцена теряет фокус; sceneDidEnterBackground — сцена скрыта. AppDelegate при этом отвечает за глобальные события (загрузка данных, пуш-уведомления), а SceneDelegate — за состояние UI каждого окна. В SwiftUI lifecycle обрабатывается через environment-значение @Environment(\.scenePhase): .active, .inactive, .background — это даёт единый API для SwiftUI и UIKit приложений.

Жизненный цикл Android: Application и ProcessLifecycleOwner

В Android lifecycle начинается с класса Application — синглтона, который создаётся до любой Activity. Метод Application.onCreate() — первая точка входа, используется для глобальной инициализации (Analytics, DI, Crash Reporting). После этого запускается Activity с последовательностью: onCreate() → onStart() → onResume(). При сворачивании: onPause() → onStop() → onSaveInstanceState(). При уничтожении: onDestroy(). При возвращении: onRestart() → onStart() → onResume().

ProcessLifecycleOwner (из AndroidX Lifecycle 2.2+) отслеживает lifecycle всего процесса, а не отдельной Activity. Он предоставляет два состояния: ON_RESUME (приложение в foreground) и ON_STOP (приложение скрыто). ProcessLifecycleOwner решает проблему «когда приложение ушло в фон» на уровне процесса — это критично для SDK, библиотек и модульных приложений. В Jetpack Compose lifecycle управляется через LifecycleEventObserver и collectAsStateWithLifecycle, который автоматически приостанавливает сбор данных при фоновом режиме. Android 14 (API 34) добавил уведомление о foreground service lifecycle через Service.onTimeout — сервис должен завершиться за 6 часов, иначе система останавливает его принудительно.

Сравнение lifecycle iOS и Android

iOS Android Описание
Not Running Приложение не запущено
didFinishLaunching Application.onCreate Первая инициализация при запуске
Active onResume Приложение видимо и принимает ввод
Inactive onPause Временная потеря фокуса (звонок, шторка)
Background onStop Приложение скрыто, код может выполняться
Suspended Код не выполняется, память зарезервирована
Will Terminate onDestroy Приложение завершается

Основное различие: iOS принудительно переводит приложение в Suspended (код не выполняется) через 5-10 секунд после ухода в фон. Android позволяет фоновую работу (сервисы, WorkManager) в течение более длительного времени, но с ограничениями Doze Mode (Android 6+) и фоновых ограничений (Android 12+). ProcessLifecycleOwner в Android — аналог UIApplicationDidEnterBackgroundNotification в iOS с тем отличием, что он срабатывает при любом переходе в фон, а не только после потери фокуса.

Примеры кода

iOS: AppDelegate с lifecycle-методами

Базовая реализация AppDelegate с обработкой всех состояний жизненного цикла. Сохранение данных при переходе в фон и обновление UI при возвращении.

swift
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        Analytics.shared.initialize()
        return true
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        NotificationCenter.default.post(name: .appWillResignActive, object: nil)
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        CoreDataManager.shared.saveContext()
        UserDefaults.standard.synchronize()
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        NetworkManager.shared.refreshSession()
    }
}

AppDelegate — центральная точка lifecycle. applicationDidEnterBackground — критический метод: iOS даёт ~5 секунд на сохранение. applicationDidBecomeActive — обновите UI, перезапустите анимации. Для SceneDelegate (iOS 13+) логика lifecycle разносится по сценам: sceneDidBecomeActive / sceneDidEnterBackground управляют отдельными окнами.

iOS: SceneDelegate (iOS 13+)

SceneDelegate для многоконных приложений iPad. Каждая сцена имеет собственный lifecycle, независимый от других окон.

swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        window = UIWindow(windowScene: windowScene)
        window?.rootViewController = ViewController()
        window?.makeKeyAndVisible()
    }

    func sceneDidBecomeActive(_ scene: UIScene) {
        PlayerManager.shared.resume()
    }

    func sceneDidEnterBackground(_ scene: UIScene) {
        PlayerManager.shared.pause()
        CoreDataManager.shared.saveContext()
    }

    func sceneDidDisconnect(_ scene: UIScene) {
        PlayerManager.shared.cleanup()
    }
}

SceneDelegate управляет lifecycle отдельной сцены. sceneDidBecomeActive / sceneDidEnterBackground — аналог AppDelegate-методов для конкретного окна. sceneDidDisconnect вызывается при закрытии сцены (пользователь закрыл окно на iPad). Для сохранения совместимости с iOS 12 и ниже, AppDelegate должен дублировать SceneDelegate-логику. В iOS 17+ можно использовать @Observable для автоматической приостановки/возобновления задач на основе scenePhase.

Android: Application с ProcessLifecycleOwner

ProcessLifecycleOwner отслеживает, когда приложение находится в foreground/background на уровне процесса. Это оптимальный способ для глобального lifecycle-менеджмента.

kotlin
import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

class MainApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ProcessLifecycleOwner.get().lifecycle.addObserver(AppLifecycleObserver())
    }
}

class AppLifecycleObserver : LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun onEnterForeground() {
        Analytics.shared.onForeground()
        NetworkMonitor.shared.start()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun onEnterBackground() {
        Analytics.shared.onBackground()
        NetworkMonitor.shared.stop()
    }
}

ProcessLifecycleOwner — единственный корректный способ отследить переход в фон на уровне приложения. ON_START срабатывает, когда приложение становится видимым (foreground), ON_STOP — когда полностью скрыто (background). В отличие от Activity lifecycle, ProcessLifecycleOwner не привязан к конкретному экрану. Для Jetpack Compose используйте LifecycleResumeEffect или collectAsStateWithLifecycle вместо ручного наблюдения.

Android: Activity Lifecycle с ViewModel

ViewModel + Lifecycle — правильная архитектура Android для работы с lifecycle. ViewModel автоматически очищается при onDestroy, предотвращая утечки.

kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData

class TimerViewModel : ViewModel() {

    private val _time = MutableLiveData<Long>()
    val time: LiveData<Long> = _time

    private var startTime = System.currentTimeMillis()

    init {
        updateTime()
    }

    private fun updateTime() {
        _time.value = System.currentTimeMillis() - startTime
    }

    override fun onCleared() {
        super.onCleared()
        Logger.d("ViewModel cleared — освобождение ресурсов")
    }
}

// В Activity
class TimerActivity : AppCompatActivity() {

    private val viewModel: TimerViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Logger.d("Activity created")
    }

    override fun onResume() {
        super.onResume()
        viewModel.time.observe(this) { Logger.d("Time: $it") }
    }

    override fun onPause() {
        super.onPause()
        Logger.d("Activity paused — приостановка анимаций")
    }

    override fun onDestroy() {
        super.onDestroy()
        Logger.d("Activity destroyed — очистка")
    }
}

ViewModel переживает поворот экрана и уничтожается только при finish() Activity. onCleared() — место для освобождения ресурсов, отписки от потоков. LiveData автоматически приостанавливает наблюдение при onPause и возобновляет при onResume — это даёт защиту от утечек и крашей при фоновой работе. В Compose используйте collectAsStateWithLifecycle() для той же цели.

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

Что происходит, когда пользователь сворачивает iOS-приложение?

При сворачивании приложение переходит из active в inactive (кратковременно), затем в background. Через несколько секунд система может перевести его в suspended — код не выполняется, память зарезервирована. При нехватке памяти suspended-приложениеterminate (willTerminate не вызывается). Сохраняйте данные в applicationDidEnterBackground — это последняя гарантированная точка для сохранения.

Нужно ли обрабатывать все состояния App Lifecycle?

Минимально обязательные: applicationDidEnterBackground — сохранить пользовательские данные; applicationWillEnterForeground — обновить UI; в Android onPause — приостановить анимации/сенсоры. ProcessLifecycleOwner упрощает обработку: onResume — onPause для foreground, onStart — onStop для видимости. Остальные состояния обрабатывайте по необходимости — не все состояния критичны для каждого приложения.

Чем SceneDelegate отличается от AppDelegate?

AppDelegate — глобальный делегат всего приложения (запуск, переход в фон). SceneDelegate (iOS 13+) управляет lifecycle отдельного окна (сцены) — в многоконных iPad приложениях каждая сцена имеет свой lifecycle. Для iOS 12 и ниже весь lifecycle обрабатывается через AppDelegate. С iPadOS 16+ SceneDelegate обязателен для Stage Manager.

Что такое ProcessLifecycleOwner в Android?

ProcessLifecycleOwner — компонент из AndroidX Lifecycle, который отслеживает lifecycle всего приложения (процесса), а не отдельной Activity. Он предоставляет два основных события: ON_RESUME (приложение в foreground) и ON_STOP (приложение в background). Используется для инициализации/очистки SDK, аналитики, сетевых мониторов — всего, что должно реагировать на переход приложения в фон, независимо от текущего экрана.

Как обрабатывать lifecycle в Jetpack Compose?

В Jetpack Compose используйте LifecycleEventObserver через LocalLifecycleOwner.current.lifecycle или функцию collectAsStateWithLifecycle(). Для Compose-экранов применяйте LifecycleResumeEffect — аналог DisposableEffect, который запускается при onResume и очищается при onPause. lifecycleScope.launchWhenResumed — корутина, автоматически приостанавливаемая в фоне.

Итоги

  • App Lifecycle — конечный автомат состояний приложения, определяющий управление ресурсами, сохранение данных и стабильность.
  • iOS AppDelegate (applicationDidEnterBackground) — критический метод для сохранения данных при переходе в фон за 5 секунд.
  • iOS SceneDelegate (iOS 13+) управляет lifecycle каждой сцены отдельно — обязателен для многоконных iPad-приложений.
  • Android ProcessLifecycleOwner — глобальный наблюдатель lifecycle процесса для инициализации/очистки SDK.
  • ViewModel в Android переживает поворот экрана и очищается при finish Activity — предотвращает утечки памяти.
  • SwiftUI @Environment(\.scenePhase) — единый API для lifecycle в SwiftUI (active, inactive, background).
  • Корректная обработка lifecycle снижает потребление памяти на 30-40% и предотвращает 40% крашей при фоновой работе.

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

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

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

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