Життєвий цикл мобільного застосунку визначає, як він поводиться при запуску, згортанні, поверненні з фону та закритті. У цій статті розберемо 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, але додає нові методи. Fragments можуть бути додані, замінені, видалені без знищення 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.