Жизненный цикл мобильного приложения определяет, как оно ведёт себя при запуске, свёртывании, возврате из фона и закрытии. В этой статье разберём App Lifecycle (iOS), Activity Lifecycle (Android), Fragment Lifecycle, ViewController Lifecycle и LifecycleOwner. Понимание этих процессов критически важно для предотвращения утечек памяти, потери данных и некорректной работы приложения. Подробнее — в официальной документации Android Activity Lifecycle.
Главное
Прежде чем разбирать жизненный цикл отдельных экранов, важно понять жизненный цикл всего приложения в целом. В iOS приложение проходит через пять состояний: Not Running (не запущено), Inactive (в фоне, не принимает события), Active (активно), Background (в фоне, код выполняется) и Suspended (в фоне, код приостановлен). Управление этими состояниями происходит в AppDelegate через методы applicationDidFinishLaunching, applicationDidBecomeActive, applicationWillResignActive, applicationDidEnterBackground и applicationWillTerminate.
В Android аналогом является Application Lifecycle, который отслеживается через интерфейс Application.ActivityLifecycleCallbacks. Однако в Android больше внимания уделяется жизненному циклу Activity — отдельного экрана приложения. Это связано с тем, что Android-приложение может состоять из множества Activity, каждая со своим циклом.
Современный подход в Android — использование ProcessLifecycleOwner из библиотеки lifecycle-process. Он позволяет отслеживать состояние всего процесса без привязки к конкретной Activity. В iOS для отслеживания состояния приложения используется UISceneDelegate (начиная с iOS 13) или AppDelegate. SceneDelegate обрабатывает несколько окон (multiwindow) на iPad. Понимание App Lifecycle особенно важно для IT Sectr при разработке приложений с фоновой синхронизацией, стримингом и VoIP-звонками.
Activity — базовый компонент Android-приложения, представляющий один экран. Activity имеет чётко определённый жизненный цикл, который управляется операционной системой в ответ на действия пользователя и системные события (поворот экрана, входящий звонок, нехватка памяти).
| Метод | Описание | Что делать |
|---|---|---|
| onCreate | Вызывается один раз при создании Activity | Инициализация UI, findViewById, настройка ViewModel |
| onStart | Activity становится видимой | Запуск анимаций, регистрация BroadCastReceiver |
| onResume | Activity получает фокус ввода | Запуск камеры, сенсоров, анимаций |
| onPause | Activity теряет фокус (частично видна) | Сохранение черновиков, остановка анимаций |
| onStop | Activity не видна | Освобождение ресурсов, остановка обновлений |
| onDestroy | Activity уничтожается | Очистка всех ссылок, отписка от LiveData |
| onRestart | Вызывается перед onStart после onStop | Повторная инициализация |
Важно: onSaveInstanceState вызывается до onStop для сохранения временного состояния. Восстановление происходит в onCreate через Bundle savedInstanceState или через SavedStateHandle в ViewModel. Без правильной обработки жизненного цикла при повороте экрана приложение потеряет все несохранённые данные.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("draft", draftText)
}
override fun onDestroy() {
super.onDestroy()
// Отписка от всех подписок
}
}
В Jetpack Compose жизненный цикл Activity остаётся неизменным, но Compose предоставляет дополнительные инструменты: Lifecycle-aware composition через LifecycleOwner, эффекты LifecycleEventEffect и DisposableEffect для автоматической очистки ресурсов при уничтожении.
Fragment в Android живёт внутри Activity и имеет свой жизненный цикл, который частично совпадает с Activity, но добавляет новые методы. Fragment могут быть добавлены, заменены, удалены без уничтожения Activity, что делает их более гибкими, но и более сложными.
Основные методы Fragment Lifecycle: onAttach — Fragment прикреплён к Activity (первый вызов); onCreate — инициализация данных; onCreateView — создание View; onViewCreated — View создана, можно настраивать UI; onStart — Fragment видим; onResume — Fragment в фокусе; onPause — Fragment теряет фокус; onStop — Fragment не видим; onDestroyView — View уничтожается; onDestroy — Fragment уничтожается; onDetach — Fragment откреплён от Activity.
Ключевое отличие от Activity: onCreateView и onDestroyView могут вызываться несколько раз (например, при переключении TabLayout), в то время как onCreate вызывается один раз. Соответственно, инициализацию View нужно делать в onViewCreated, а не в onCreateView. Ресурсы, связанные с View (например, адаптеры RecyclerView), должны очищаться в onDestroyView.
UIViewController — базовый класс для управления экранами в iOS. Его жизненный цикл состоит из последовательности методов, которые UIKit вызывает автоматически. Понимание этого цикла критически важно для правильной инициализации UI, работы с данными и памяти.
| Метод | Когда вызывается | Типичное использование |
|---|---|---|
| loadView | Когда View Controller загружает свою иерархию View | Кастомная инициализация без storyboard |
| viewDidLoad | После загрузки View в память (один раз) | Настройка UI, загрузка начальных данных |
| viewWillAppear | Перед появлением View на экране | Обновление данных, подписка на уведомления |
| viewDidAppear | После появления View на экране | Запуск анимаций, старт анимаций трекинга |
| viewWillDisappear | Перед исчезновением View с экрана | Сохранение состояния, отписка от уведомлений |
| viewDidDisappear | После исчезновения View с экрана | Остановка анимаций, освобождение ресурсов |
| dealloc | При уничтожении View Controller | Освобождение всех ресурсов |
Важно: viewDidLoad вызывается только один раз за жизнь View Controller. Для обновления данных при каждом появлении используйте viewWillAppear. Если вы подписываетесь на NotificationCenter в viewWillAppear, обязательно отписывайтесь в viewDidDisappear, чтобы избежать утечек памяти.
SwiftUI управляет жизненным циклом View через структуры View. Вместо методов-колбэков SwiftUI использует модификаторы onAppear и onDisappear. Для глобальных состояний приложения используется App Lifecycle через App и Scene протоколы. SwiftUI автоматически управляет созданием и уничтожением View на основе состояния, что упрощает разработку, но требует понимания identity и lifetime View.
struct ContentView: View {
var body: some View {
Text("Hello")
.onAppear {
print("View появилась")
}
.onDisappear {
print("View исчезла")
}
}
}
LifecycleOwner — интерфейс из Android Architecture Components, который маркирует объект, имеющий жизненный цикл (Activity, Fragment). LifecycleObserver — интерфейс, позволяющий объекту подписываться на события LifecycleOwner. Вместе они формируют основу реактивного управления жизненным циклом в современной Android-разработке.
Вместо явного вызова методов в onStart/onStop рекомендуется использовать DefaultLifecycleObserver (замена устаревшего LifecycleObserver с аннотациями @OnLifecycleEvent). Это подход, продвигаемый Google для ViewModel и других компонентов, которые должны реагировать на жизненный цикл, не имея прямых ссылок на Activity или Fragment.
class MyObserver : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
// Подписка на обновления
}
override fun onStop(owner: LifecycleOwner) {
// Отписка
}
}
В IT Sectr мы используем LifecycleOwner во всех проектах на Android. ViewModel подписывается на LifecycleOwner Activity через viewModelScope и lifecycleScope, что гарантирует автоматическую отмену корутин при уничтожении Activity. Это предотвращает утечки памяти и делает код чище и безопаснее.
Часто задаваемые вопросы
Activity проходит шесть состояний: Created (onCreate), Started (onStart), Resumed (onResume), Paused (onPause), Stopped (onStop), Destroyed (onDestroy).
Порядок: loadView → viewDidLoad → viewWillAppear → viewDidAppear → viewWillDisappear → viewDidDisappear. viewDidLoad вызывается один раз.
LifecycleOwner — компонент Android Architecture Components, который владеет жизненным циклом Activity или Fragment. Позволяет подписываться на события через LifecycleObserver.
iOS приложение проходит пять состояний: Not Running, Inactive, Active, Background, Suspended. Переходы управляются через UIApplicationDelegate.
Saved State — механизм Android для сохранения состояния Activity/Fragment при повороте экрана или пересоздании процесса. Использует onSaveInstanceState и SavedStateHandle.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.