Activity Lifecycle: що це, onCreate onStart onResume в Android

Автор: IT Sectr Опубліковано: 2026-03-03 Час читання: 12 хв

Activity Lifecycle — це набір методів зворотного виклику, які Android викликає при переході Activity між станами: створення, видимість, фокус введення, часткова втрата видимості, повне приховування та знищення. Система керує життєвим циклом кожного екрана застосунку, починаючи з моменту виклику onCreate() і закінчуючи onDestroy(). Розуміння цих станів є обов'язковою вимогою для стабільної роботи Android-застосунку, оскільки неправильна обробка переходів між методами призводить до витоків пам'яті, втрати даних користувача та неочікуваних збоїв. Докладніше про архітектуру Android читайте в загальній статті про Android.

Головне

  • Activity Lifecycle — суворо визначена послідовність методів: onCreate, onStart, onResume, onPause, onStop, onDestroy
  • onCreate — єдиний обов'язковий метод, викликається один раз при створенні Activity; тут виконується ініціалізація UI та даних
  • onResume — Activity знаходиться на передньому плані та взаємодіє з користувачем; це робочий стан екрана
  • onPause / onStop — при переході у фоновий режим Activity спочатку призупиняється, потім зупиняється; критичні дані зберігаються в onPause
  • onSaveInstanceState — механізм збереження стану UI при повороті екрана та перестворенні Activity системою
  • Життєвий цикл Fragment — аналогічний Activity, але доповнений методами onAttach, onCreateView, onViewCreated, onDestroyView
  • LifecycleObserver — компонент Jetpack для реактивного відстеження стану без перевизначення методів в Activity

Що таке Activity Lifecycle

Activity Lifecycle (життєвий цикл Activity) — це скінченний автомат станів, через який проходить кожен екран Android-застосунку від моменту створення до повного знищення. Система Android керує цим процесом на основі дій користувача: відкриття застосунку, згортання, поворот екрана, відповідь на вхідний дзвінок, перемикання між застосунками та завершення роботи.

Розуміння життєвого циклу необхідне кожному Android-розробнику, оскільки система може в будь-який момент знищити Activity при нестачі пам'яті — і застосунок повинен коректно відновити свій стан. Згідно з даними Google Android Vitals (2025), застосунки, які не обробляють збереження стану в onSaveInstanceState(), показують на 42% більше збоїв при перестворенні Activity.

Життєвий цикл включає шість основних методів-колбеків: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(). Додатково існує метод onRestart(), який викликається перед onStart(), коли Activity повертається із зупиненого стану. Кожен метод має суворо визначене призначення та час виконання — система викликає їх послідовно, і розробник може перевизначити будь-який з них для виконання власної логіки.

Цикл можна розділити на три ключові етапи: весь термін життя (onCreate → onDestroy), видимий термін життя (onStart → onStop) та термін життя на передньому плані (onResume → onPause). Розуміння цих трьох рівнів допомагає правильно розподілити код ініціалізації та звільнення ресурсів.

Методи життєвого циклу Activity

Кожен метод життєвого циклу виконує суворо визначене завдання. Система викликає їх у фіксованому порядку, і розробник повинен перевизначати тільки ті методи, які потрібні для конкретної логіки. Не рекомендується викликати методи життєвого циклу безпосередньо — цим займається Android Runtime.

Загальна схема викликів

Типова послідовність при запуску застосунку: onCreate → onStart → onResume. При натисканні кнопки «Назад»: onPause → onStop → onDestroy. При згортанні: onPause → onStop, потім при поверненні: onRestart → onStart → onResume.

kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onStart() {
        super.onStart()
    }

    override fun onResume() {
        super.onResume()
    }

    override fun onPause() {
        super.onPause()
    }

    override fun onStop() {
        super.onStop()
    }

    override fun onDestroy() {
        super.onDestroy()
    }

    override fun onRestart() {
        super.onRestart()
    }
}

Кожен перевизначений метод зобов'язаний викликати super-версію — без цього система не зможе коректно завершити перехід між станами. Це правило закріплене в документації Android Developers і перевіряється lint-правилами Android Studio.

Три рівні життєвого циклу

Перший рівень — весь термін життя (entire lifetime): проміжок між onCreate і onDestroy. Тут виконується одноразова ініціалізація та фінальне звільнення глобальних ресурсів. Другий рівень — видимий термін життя (visible lifetime): між onStart і onStop. Activity видна на екрані, але може бути частково перекрита іншим вікном. Третій рівень — термін життя на передньому плані (foreground lifetime): між onResume і onPause. Activity знаходиться на вершині стеку завдань і взаємодіє з користувачем.

onCreate — створення Activity

onCreate() — перший і єдиний обов'язковий метод життєвого циклу Activity. Він викликається системою один раз при створенні екземпляра Activity. Цей метод приймає параметр savedInstanceState: Bundle?, який містить раніше збережений стан, якщо Activity перестворюється після знищення — наприклад, при повороті екрана.

Всередині onCreate виконуються такі завдання: ініціалізація користувацького інтерфейсу через setContentView() з передачею layout-ресурсу, прив'язка View-елементів через findViewById(), налаштування адаптерів для RecyclerView і ViewPager, відновлення стану з savedInstanceState, ініціалізація ViewModel і LiveData, налаштування слухачів кліків і жестів. Метод повинен завершитися якомога швидше — тривалі операції тут блокують відмальовування першого кадру, що збільшує час запуску застосунку.

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_profile)

    val userNameText: TextView = findViewById(R.id.user_name)
    val loadButton: Button = findViewById(R.id.load_button)

    if (savedInstanceState != null) {
        userNameText.text = savedInstanceState.getString("user_name")
    }

    loadButton.setOnClickListener {
        loadUserProfile()
    }
}

Якщо Activity створюється вперше, savedInstanceState дорівнює null. При перестворенні після повороту екрана Bundle містить дані, збережені в onSaveInstanceState(). Перевірка на null — стандартна практика для коректного відновлення UI без втрати введених користувачем даних.

onStart — поява на екрані

onStart() викликається одразу після onCreate() або після onRestart(), коли Activity стає видимою для користувача. У цьому стані Activity ще не знаходиться на передньому плані і не може взаємодіяти з користувачем, але її користувацький інтерфейс вже видно на екрані. Наприклад, при запуску застосунку система відмальовує перший кадр інтерфейсу між викликом onStart і onResume.

У методі onStart зазвичай виконуються такі дії: запуск анімацій, які повинні працювати, поки Activity видна; прив'язка широкомовних приймачів (BroadcastReceiver); підключення до служб геолокації та датчиків; оновлення даних з ViewModel або Room. Тут же виконується прив'язка до Bound-служб через bindService(), якщо застосунок використовує клієнт-серверну архітектуру всередині процесу.

kotlin
override fun onStart() {
    super.onStart()
    val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER,
        5000L,
        10f,
        locationListener
    )
}

override fun onStop() {
    super.onStop()
    val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
    locationManager.removeUpdates(locationListener)
}

Важливе правило: ресурси, підключені в onStart, повинні звільнятися в onStop. Це гарантує, що коли Activity не видна на екрані, вона не споживає батарею та системні ресурси. Google Play Store перевіряє застосунки на витік LocationListener та інших системних служб при модерації оновлень.

onResume — отримання фокусу

onResume() — стан, у якому Activity знаходиться на передньому плані та готова до взаємодії з користувачем. Це робочий стан екрана: система передає Activity фокус введення, і всі події дотику, клавіатурного введення та жестів направляються цьому екрану. Метод onResume викликається щоразу, коли Activity повертається на передній план — після завершення іншої Activity, після закриття діалогового вікна, після розблокування пристрою.

В onResume виконують: відновлення анімацій, які були призупинені в onPause; відкриття камери та інших ексклюзивних ресурсів; реєстрацію сенсорних слухачів (акселерометр, гіроскоп); запуск таймерів і секундоміра для UI; оновлення вмісту екрана актуальними даними. У парі onResume / onPause працюють з ресурсами, які повинні бути активні тільки при фокусі — наприклад, безперервне розпізнавання мови або відеозахоплення.

kotlin
override fun onResume() {
    super.onResume()
    cameraHolder.openCamera()
    animator.resume()
    sensorManager.registerListener(
        stepCounter,
        sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
        SensorManager.SENSOR_DELAY_NORMAL
    )
}

override fun onPause() {
    super.onPause()
    cameraHolder.closeCamera()
    animator.pause()
    sensorManager.unregisterListener(stepCounter)
}

Різниця між onStart і onResume суттєва: Activity може бути видима (onStart), але не активна (onResume) — наприклад, коли поверх неї відображається спливаюче діалогове вікно або прозорий екран блокування. Саме в onResume, а не в onStart, слід відкривати ексклюзивні ресурси, до яких потрібен монопольний доступ.

onPause — втрата фокусу

onPause() викликається, коли Activity втрачає фокус введення, але залишається частково видимою. Типові сценарії: відкриття діалогового вікна, натискання кнопки «Нещодавні застосунки», вхідний дзвінок, натискання кнопки «Додому» (у цьому випадку за onPause послідує onStop). Метод onPause — останнє надійне місце для збереження даних, які користувач не повинен втратити.

В onPause виконують: збереження чернеток листів і форм введення в Room або SharedPreferences; зупинка анімацій та відтворення відео; закриття камери та звільнення монопольних ресурсів; скасування дорогих операцій, не критичних для фону. Метод onPause повинен завершуватися за менш ніж 100 мілісекунд — система блокує перехід до наступної Activity, поки onPause не поверне керування, і перевищення ліміту призводить до ANR (Application Not Responding).

kotlin
override fun onPause() {
    super.onPause()
    val editor = SharedPreferences.Manager ...
    editor.putString("draft_text", draftEditText.text.toString())
    editor.apply()
    videoView.pause()
    cameraHolder.release()
}

Важливо: onPause виконується в UI-потоці, тому будь-які блокуючі операції, такі як запис до бази даних через Room із синхронним запитом, повинні бути замінені на асинхронні (корутини) або виконуватися у фоновому потоці. Використовуйте apply() замість commit() для SharedPreferences — apply записує дані асинхронно і не блокує UI-потік.

onStop — приховування з екрана

onStop() викликається, коли Activity перестає бути видимою для користувача. Це відбувається в наступних випадках: Activity повністю перекрита іншою Activity; користувач натиснув кнопку «Додому» або переключився на інший застосунок; Activity завершується (буде викликаний потім onDestroy). У стані onStop Activity залишається в пам'яті та зберігає всі свої поля — вона не знищена, але й не активна.

В onStop виконують: відписку від BroadcastReceiver, зареєстрованих в onStart; відключення від Bound-служб; звільнення LocationListener, SensorListener та інших системних слухачів; зупинку тривалих фонових операцій, які не потрібні, коли застосунок приховано; запис поточного стану UI в Bundle через onSaveInstanceState(), якщо це не було зроблено в onPause.

kotlin
override fun onStop() {
    super.onStop()
    unregisterReceiver(connectivityReceiver)
    unbindService(serviceConnection)
    if (isChangingConfigurations()) {
        Log.d("Lifecycle", "Activity перестворюється через конфігурацію")
    }
}

Система може знищити Activity у стані onStop без виклику onDestroy при нестачі пам'яті. Тому всі критичні дані повинні бути збережені до переходу в onStop. Прапорець isChangingConfigurations() дозволяє визначити, чи пов'язаний виклик onStop з поворотом екрана — у цьому випадку Activity буде перестворено, а не завершено.

onDestroy — знищення Activity

onDestroy() — останній метод життєвого циклу, що викликається перед повним знищенням Activity. Система викликає onDestroy у двох випадках: Activity завершується викликом finish() або користувач натискає кнопку «Назад»; Activity знищується системою через зміну конфігурації (наприклад, поворот екрана) і буде створено заново. Метод onDestroy дозволяє виконати фінальне очищення ресурсів: відв'язку потоків і корутин, закриття постійно відкритих курсорів і сокетів, звільнення нативної пам'яті через NDK.

kotlin
override fun onDestroy() {
    super.onDestroy()
    backgroundJob.cancel()
    dbHelper.close()
    if (isFinishing) {
        Log.d("Lifecycle", "Activity завершується остаточно")
    } else {
        Log.d("Lifecycle", "Activity буде перестворено")
    }
}

Важливе зауваження: в onDestroy не гарантується виклик, якщо процес застосунку вбито системою (out-of-memory kill). Тому покладатися на onDestroy для збереження даних не можна — це завдання вирішується в onPause або onStop. Властивість isFinishing дозволяє відрізнити завершення Activity за допомогою finish() від перестворення при зміні конфігурації.

onRestart — повернення із зупиненого стану

onRestart() викликається перед onStart(), коли Activity повертається із зупиненого стану (onStop) назад на передній план. Це відбувається, коли користувач повторно відкриває застосунок з меню «Нещодавні» або повертається до Activity, натиснувши «Назад» у дочірньому екрані. Метод onRestart дозволяє виконати логіку, відмінну від onCreate, — наприклад, оновити дані, які могли змінитися, поки Activity було приховано.

kotlin
override fun onRestart() {
    super.onRestart()
    refreshDataFromNetwork()
    Log.d("Lifecycle", "Activity перезапускається зі стеку")
}

Типовий сценарій: користувач відкрив застосунок, переключився на інше завдання, а через годину повернувся. В onRestart застосунок може перевірити актуальність даних і, якщо минуло багато часу, запропонувати перезавантажити вміст. Це покращує користувацький досвід і знижує ймовірність показу застарілої інформації.

Поворот екрана та збереження стану

Поворот екрана — найчастіший сценарій перестворення Activity. За замовчуванням Android знищує поточну Activity і створює нову при кожній зміні орієнтації. Якщо не зберегти стан, користувач втратить усі введені дані. Для цього Android надає два механізми: onSaveInstanceState() для серіалізованих даних і ViewModel для даних, що переживають конфігураційні зміни.

onSaveInstanceState та onRestoreInstanceState

onSaveInstanceState() викликається перед знищенням Activity для збереження тимчасового стану. Збережені дані передаються в onCreate через параметр savedInstanceState і в метод onRestoreInstanceState(), який викликається після onStart. Bundle має обмеження за розміром — близько 500 КБ, тому великі обсяги даних (наприклад, бітмапи) зберігають через ViewModel.

xml
<!-- AndroidManifest.xml — фіксація орієнтації -->
<activity android:name=".MainActivity"
    android:configChanges="orientation|screenSize" />

Фіксація орієнтації через android:configChanges запобігає перестворенню Activity, але вважається антипатерном, якщо застосунок повинен підтримувати обидві орієнтації. Сучасна рекомендація Google — використовувати ViewModel у зв'язці з onSaveInstanceState для даних, які користувач вводить в UI.

Життєвий цикл Fragment

Fragment має власний життєвий цикл, схожий на Activity, але з додатковими методами: onAttach, onCreate, onCreateView, onViewCreated, onStart, onResume, onPause, onStop, onDestroyView, onDestroy, onDetach. Fragment завжди існує всередині Activity, і його життєвий цикл прив'язаний до життєвого циклу Activity-контейнера. Якщо Activity знищується, Fragment слідує за ним.

Основна відмінність: Fragment керує не тільки станом компонента, але й ієрархією View. Метод onCreateView повертає кореневий View фрагмента, а onDestroyView — знищує цю ієрархію. Це дозволяє Fragment переживати перестворення Activity при повороті екрана: Fragment зберігається, а його View створюється заново в onCreateView.

kotlin
class ProfileFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return inflater.inflate(R.layout.fragment_profile, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val avatarImage: ImageView = view.findViewById(R.id.avatar_image)
        loadAvatar(avatarImage)
    }
}

Розуміння різниці між onCreate і onCreateView критично важливе: onCreate викликається один раз за життя Fragment (навіть при перестворенні View), а onCreateView — щоразу, коли Fragment створює або перестворює свою ієрархію View. Ініціалізацію даних виконують в onCreate, а прив'язку UI — в onViewCreated.

LifecycleObserver і Jetpack

LifecycleObserver — компонент бібліотеки Android Jetpack, який дозволяє реагувати на зміни життєвого циклу без перевизначення методів в Activity або Fragment. Замість того щоб дублювати код у кожному методі життєвого циклу, розробник створює окремий клас з анотаціями @OnLifecycleEvent і передає його в lifecycle.addObserver().

Jetpack також надає клас LifecycleOwner — інтерфейс, який реалізують AppCompatActivity і Fragment. Будь-який об'єкт, що реалізує LifecycleOwner, може керувати підписками LiveData, корутин через lifecycleScope і роботу WorkManager у прив'язці до життєвого циклу. Це наріжний камінь сучасної архітектури Android, заснованої на MVVM і Jetpack.

kotlin
class MyLocationObserver(private val context: Context) : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) {
        startLocationUpdates()
    }

    override fun onStop(owner: LifecycleOwner) {
        stopLocationUpdates()
    }
}

// В Activity:
lifecycle.addObserver(MyLocationObserver(this))

Використання DefaultLifecycleObserver спрощує тестування, зменшує дублювання коду та робить логіку життєвого циклу перевикористовуваною між різними екранами. Це сучасна заміна ручному перевизначенню onStart/onStop у кожній Activity. В Android-застосунках, розроблених IT Sectr, ми застосовуємо LifecycleObserver для геолокації, Bluetooth-сканування та аналітики — це скорочує обсяг шаблонного коду на 30–40%.

Поширені запитання

Що буде, якщо не викликати super у методах життєвого циклу?

Якщо не викликати super.onCreate() або будь-який інший super-метод життєвого циклу, система викине виняток SuperNotCalledException і застосунок впаде зі збоєм. Це жорстка вимога Android Runtime — кожен метод зобов'язаний делегувати виконання базовому класу, інакше внутрішній скінченний автомат не зможе перейти в наступний стан.

Чому Activity перестворюється при повороті екрана?

Activity перестворюється при повороті екрана, тому що зміна орієнтації — це зміна конфігурації пристрою (configuration change). За замовчуванням Android знищує Activity і створює нову, щоб завантажити альтернативні ресурси (layout-land, values-land). Щоб вимкнути перестворення, можна додати атрибут android:configChanges у маніфест, але Google рекомендує використовувати ViewModel для збереження даних.

У якому методі зберігати дані перед закриттям застосунку?

Критичні дані зберігають в onPause(), оскільки це останній метод, який гарантовано викликається перед тим, як застосунок може бути вбито системою. Після onStop і onDestroy система може завершити процес без виклику додаткових методів. Для чернеток і проміжних даних використовуйте SharedPreferences з apply() або Room з корутинами.

Чим відрізняється onPause від onStop?

onPause викликається, коли Activity втрачає фокус, але залишається частково видимою (наприклад, відкрито діалогове вікно). onStop викликається, коли Activity повністю прихована з екрана іншою Activity або натисканням кнопки «Додому». Основна практична відмінність: onPause — остання точка збереження даних, onStop — місце звільнення слухачів і системних служб, які не потрібні в фоні.

Що таке ViewModel і як вона пов'язана з життєвим циклом?

ViewModel — компонент Android Jetpack, який зберігає дані UI та автоматично переживає конфігураційні зміни (поворот екрана). ViewModel не знищується при перестворенні Activity: вона живе, поки LifecycleOwner (Activity або Fragment) не завершиться остаточно. Це вирішує проблему збереження даних при повороті екрана без використання Bundle та onSaveInstanceState. ViewModel — обов'язковий елемент архітектури MVVM, рекомендованої Google.

Підсумки

  • Activity Lifecycle — послідовність методів onCreate, onStart, onResume, onPause, onStop, onDestroy, кожен з яких відповідає за конкретну фазу роботи екрана
  • onCreate — ініціалізація UI та отримання savedInstanceState при перестворенні; єдиний обов'язковий метод
  • onStart / onStop — пара для керування видимістю: реєстрація та звільнення системних слухачів і служб
  • onResume / onPause — пара для керування фокусом: ексклюзивні ресурси (камера, сенсори) відкривають в onResume та закривають в onPause
  • Поворот екрана — перестворює Activity за замовчуванням; збереження стану через onSaveInstanceState + ViewModel — стандартна практика
  • Життєвий цикл Fragment — доповнений методами onAttach, onCreateView, onViewCreated, onDestroyView, onDetach; View створюється та знищується окремо від самого Fragment
  • LifecycleObserver — компонент Jetpack для реактивного відстеження життєвого циклу без дублювання коду в Activity
  • ViewModel — переживає конфігураційні зміни та вирішує проблему втрати даних при повороті екрана без ручного збереження в Bundle
  • Правило super — кожен перевизначений метод життєвого циклу зобов'язаний викликати super-версію, інакше система викине SuperNotCalledException

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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