onCreate — що це таке, ініціалізація Activity в Android

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

onCreate — це перший і єдиний обов’язковий метод життєвого циклу Activity та Fragment в Android. Система викликає його один раз при створенні компонента, передаючи параметр Bundle з попередньо збереженим станом. Всередині onCreate розробник ініціалізує користувацький інтерфейс, прив’язує елементи View, налаштовує обробники подій та відновлює дані з savedInstanceState. Без коректної реалізації onCreate жоден Android-додаток не може запуститися — це точка входу для кожного екрану. Докладніше про загальний життєвий цикл Activity читайте в статті Activity Lifecycle.

Головне

  • onCreate — перший і єдиний обов’язковий метод життєвого циклу; викликається один раз при створенні Activity або Fragment
  • Параметр Bundle — savedInstanceState містить дані, збережені в onSaveInstanceState, або null, якщо Activity створюється вперше
  • setContentView — обов’язковий виклик всередині onCreate для Activity; пов’язує XML-розмітку з кодом
  • Ініціалізація UI — findViewById, налаштування адаптерів RecyclerView, встановлення слухачів кліків — типові завдання onCreate
  • Fragment.onCreate — відрізняється від Activity: тут не викликають setContentView, а розмітку передають через onCreateView
  • Обмеження часу — onCreate має завершитися за 5 секунд (ANR threshold), довгі операції переносяться в фоновий потік
  • ViewModel та onCreate — ініціалізація ViewModel в onCreate дозволяє даним пережити поворот екрану без втрати

Що таке onCreate в Android

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

Метод onCreate визначено в класі android.app.Activity та в класі androidx.fragment.app.Fragment. Обидва варіанти виконують схожі завдання: ініціалізація компонента, налаштування UI та відновлення стану. Однак конкретна реалізація відрізняється — Activity використовує setContentView для завантаження розмітки, а Fragment повертає View через onCreateView. Розробник повинен перевизначити хоча б onCreate в Activity — без цього Android не зможе відобразити екран.

onCreate викликається суворо один раз за повний життєвий цикл екземпляра Activity. Навіть при повороті екрану новий екземпляр Activity отримує новий виклик onCreate з Bundle від попереднього екземпляра. Це робить onCreate ідеальним місцем для одноразової ініціалізації: завантаження даних, створення адаптерів, налаштування DI-компонентів через Dagger або Hilt.

onCreate в Activity

В Activity метод onCreate виконує чотири ключові завдання: завантаження layout-розмітки, ініціалізація елементів View, відновлення стану з Bundle та налаштування первинних обробників подій. Обов’язковий мінімальний код в onCreate — це виклик super.onCreate(savedInstanceState) та setContentView(R.layout.activity_main).

kotlin
class MainActivity : AppCompatActivity() {
    private var binding: ActivityMainBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ViewBinding — сучасна заміна findViewById
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        // Ініціалізація за допомогою binding
        binding?.apply {
            welcomeText.text = getString(R.string.welcome)
            startButton.setOnClickListener { startGame() }
        }

        // Відновлення стану
        if (savedInstanceState != null) {
            score = savedInstanceState.getInt("score", 0)
            binding?.scoreText?.text = score.toString()
        }
    }
}

Сучасна практика використовує ViewBinding замість findViewById. ViewBinding генерує клас ActivityMainBinding на етапі компіляції, що усуває помилки з некоректними ID та скорочує об’єм шаблонного коду. Google рекомендує ViewBinding як стандартний спосіб доступу до View в Activity та Fragment починаючи з Android Studio 3.6.

Порядок дій в onCreate має бути суворим: спочатку super, потім setContentView, потім усе інше. Виклик findViewById до setContentView повертає null — розмітка ще не завантажена, і елементи View не існують в ієрархії. Це одна з найчастіших помилок початківців Android-розробииків.

onCreate в Fragment

onCreate в Fragment відрізняється від Activity: тут не викликають setContentView, а лише виконують ініціалізацію даних, не пов’язаних з UI. Fragment розділяє створення компонента та створення View на два окремі методи: onCreate (викликається один раз) та onCreateView (викликається кожного разу при створенні або перестворенні View).

kotlin
class UserListFragment : Fragment() {
    private lateinit var viewModel: UserViewModel
    private var binding: FragmentUserListBinding? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Ініціалізація ViewModel — переживає перестворення View
        viewModel = ViewModelProvider(this)[UserViewModel::class.java]

        // Аргументи з FragmentManager
        arguments?.let {
            viewModel.loadUser(it.getString("user_id") ?: "")
        }

        // Збереження при повороті
        retainInstance = true
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentUserListBinding.inflate(inflater, container, false)
        return binding!!.root
    }
}

Ключова відмінність між onCreate Activity та Fragment: onCreate в Fragment не повинен містити код, пов’язаний з View, оскільки View може бути знищений та створений заново (наприклад, при перемиканні вкладок ViewPager), а onCreate викликається лише один раз. Завантаження даних, налаштування ViewModel та ініціалізація адаптерів — завдання onCreate, а прив’язка View — завдання onViewCreated.

savedInstanceState та відновлення стану

Параметр savedInstanceState в onCreate — це механізм збереження та відновлення тимчасового стану Activity або Fragment. Коли система знищує Activity (поворот екрану, нестача пам’яті), вона викликає onSaveInstanceState(), до якого розробник поміщує пари ключ-значення в Bundle. При створенні нового екземпляра цей Bundle повертається в onCreate.

Bundle підтримує такі типи даних: String, Integer, Boolean, Long, Float, Double, їхні масиви, а також об’єкти Parcelable та Serializable. Для складних об’єктів використовують Parcelable — більш продуктивний механізм серіалізації, специфічний для Android. Розмір Bundle обмежений приблизно 500 КБ — перевищення ліміту викликає TransactionTooLargeException.

kotlin
companion object {
    private const val KEY_USER_NAME = "user_name"
    private const val KEY_SCORE = "score"
}

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

    if (savedInstanceState != null) {
        userName = savedInstanceState.getString(KEY_USER_NAME) ?: ""
        currentScore = savedInstanceState.getInt(KEY_SCORE)
    }
}

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString(KEY_USER_NAME, userName)
    outState.putInt(KEY_SCORE, currentScore)
}

Важливо розуміти: onSaveInstanceState не викликається, коли користувач явно закриває Activity через finish() або кнопку «Назад». Система вважає, що користувач свідомо завершує роботу, і зберігати стан не потрібно. Тому покладатися виключно на savedInstanceState для довгострокового зберігання даних не можна — використовуйте Room, DataStore або SharedPreferences.

Часові обмеження onCreate

onCreate виконується в головному (UI) потоці, і система чекає його завершення, перніж відобразити Activity на екрані. Якщо onCreate виконується довше 5 секунд, система показує діалогове вікно ANR (Application Not Responding) та пропонує користувачеві закрити додаток. Довгі операції, такі як завантаження даних з мережі або читання з бази даних, повинні бути винесені в фоновий потік.

Згідно з рекомендаціями Google Android Performance (2025), onCreate має завершитися за менше ніж 1 секунду на пристроях середнього сегменту. Для цього слід: використовувати лениву ініціалізацію (lazy делегат в Kotlin), відкладати завантаження важких даних на onResume або через корутини, застосовувати ViewStub для рідко використовуваних UI-компонентів, профілювати час запуску через Android Vitals.

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

    // Ленива ініціалізація — об’єкт створюється тільки при першому зверненні
    val heavyData by lazy {
        HeavyDataLoader.load()
    }

    // Завантаження даних у фоновому потоці через lifecycleScope
    lifecycleScope.launch(Dispatchers.IO) {
        val users = userDao.getAllUsers()
        withContext(Dispatchers.Main) {
            adapter.submitList(users)
        }
    }
}

Інструменти профілювання: Android Studio Profiler (вкладка CPU) показує точний час виконання кожного методу. В Android Vitals (консоль Google Play) можна відстежувати метрику «Час холодного старту» — якщо onCreate вашої Activity перевищує 500 мс, консоль позначає це як проблему продуктивності. Ми в IT Sectr використовуємо Macrobenchmark-тести для автоматичного контролю часу запуску кожної Activity в CI-пайплайні.

ViewModel та onCreate

ViewModel — найкращий спосіб ініціалізації даних в onCreate, які повинні пережити поворот екрану. ViewModel створюється в onCreate через ViewModelProvider і автоматично зберігається при змінах конфігурації. Коли Activity перестворюється після повороту, ViewModel залишається в пам’яті, і onCreate отримує той самий ViewModel без втрати даних.

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

    // ViewModel створюється один раз і переживає конфігураційні зміни
    val viewModel: ProfileViewModel =
        ViewModelProvider(this)[ProfileViewModel::class.java]

    // Спостереження LiveData — UI автоматично оновлюється при зміні даних
    viewModel.user.observe(this) { user ->
        binding?.userName?.text = user.name
        binding?.userEmail?.text = user.email
    }

    // Завантаження даних, якщо ViewModel щойно створено
    if (savedInstanceState == null) {
        viewModel.loadProfile(userId)
    }
}

Комбінація ViewModel + LiveData/StateFlow вирішує проблему повороту екрану без ручного зберігання в Bundle. ViewModel зберігає дані в пам’яті, LiveData автоматично перепідписує Activity при перестворенні, а StateFlow (з Kotlin Coroutines) додає реактивність з підтримкою корутин. Це стандартна архітектура, рекомендована Google в посібнику Guide to App Architecture.

Часті помилки при роботі з onCreate

Навіть досвідчені розробники припускають типові помилки в onCreate. Розглянемо п’ять найпоширеніших проблем та способи їх уникнути.

Робота з View до setContentView

Найчастіша помилка — спроба знайти View через findViewById до виклику setContentView. Усі елементи View створюються в момент інфляції розмітки, тому будь-яке звернення до findViewById до setContentView повертає null і викликає NullPointerException при спробі використати View. Рішення: суворий порядок — спочатку super, потім setContentView, потім findViewById або ViewBinding.

Блокування UI-потоку довгими операціями

Завантаження даних з мережі, читання з бази даних або обробка великих масивів безпосередньо в onCreate блокує відображення першого кадру. Користувач бачить чорний екран, поки onCreate не завершиться, що погіршує сприйняття швидкості роботи додатка. Рішення: використовуйте lifecycleScope.launch для асинхронних операцій, відображайте скелетон (UI placeholder) до завершення завантаження.

Ігнорування savedInstanceState

Якщо при повороті екрану не відновлювати стан з Bundle, користувач втрачає весь незбережений ввід: текст у полях форми, позицію прокрутки, вибрані елементи. Рішення: завжди перевіряйте savedInstanceState != null в onCreate для відновлення даних, навіть якщо втрата стану здається майовірною.

Витік пам’яті через анонімні класи

Анонімні класи та лямбди в onCreate можуть неявно утримувати посилання на Activity після його знищення. Наприклад, Handler, створений в onCreate, продовжує виконувати відкладені завдання навіть після знищення Activity. Рішення: використовуйте LifecycleObserver, ViewModel та lifecycleScope, які автоматично скасовують завдання при знищенні.

Надмірна ініціалізація в Fragment.onCreate

Ініціалізація View в Fragment.onCreate — це логічна помилка, оскільки View може бути перестворена без виклику onCreate. Якщо встановити слухача в onCreate, а View прив’язувати в onCreateView, то при перестворенні слухач залишиться на старій View. Рішення: усю роботу з View виконуйте в onViewCreated, а onCreate залиште лише для ініціалізації рівня даних.

Часто задавані питання

Чи обов’язково перевизначати onCreate в Activity?

Так, перевизначення onCreate обов’язкове для будь-якої Activity, яка відображає користувацький інтерфейс. Без цього неможливо викликати setContentView та завантажити XML-розмітку. Якщо Activity не має UI (наприклад, прозора Activity-заглушка), onCreate все одно перевизначають, але без виклику setContentView.

Чи може onCreate бути викликаний повторно без знищення Activity?

Ні, onCreate не може бути викликаний повторно для того ж екземпляра Activity. Якщо Activity знищена та створена заново (поворот екрану, нестача пам’яті), це вже новий екземпляр з новим викликом onCreate. Виняток — метод recreate(), який примусово знищує та перестворює Activity, але це перестворення нового екземпляра.

Що буде, якщо не викликати super.onCreate?

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

Чим onCreate в Activity відрізняється від onCreate в Fragment?

Основна відмінність: onCreate в Activity завантажує UI через setContentView, а onCreate в Fragment лише ініціалізує дані. Fragment створює View в окремому методі onCreateView, який може викликатися багаторазово (наприклад, при перемиканні вкладок), тоді як onCreate Fragment викликається один раз за час життя екземпляра Fragment.

Як передати дані з onCreate в інші методи?

Дані, ініціалізовані в onCreate, зберігаються в полях класу Activity або Fragment. Наприклад, private lateinit var binding: ActivityMainBinding оголошується на рівні класу, ініціалізується в onCreate і доступний у всіх подальших методах. Для даних, що переживають поворот екрану, використовуйте ViewModel з LiveData або StateFlow.

Підсумки

  • onCreate — обов’язковий метод життєвого циклу, викликається один раз при створенні Activity або Fragment
  • setContentView — обов’язковий виклик для Activity, завантажує XML-розмітку; для Fragment розмітку завантажують через onCreateView
  • savedInstanceState — Bundle зі збереженим станом при перестворенні; null при першому запуску
  • Обмеження часу — onCreate має виконуватися менше ніж 1 секунду, довгі операції переносять в корутини
  • ViewModel — ініціалізація ViewModel в onCreate вирішує проблему втрати даних при повороті екрану
  • Fragment vs Activity — Fragment.onCreate не містить UI-код, Activity.onCreate завантажує розмітку через setContentView
  • П’ять типових помилок — робота з View до setContentView, блокування UI, ігнорування Bundle, витік пам’яті, UI-код в Fragment.onCreate

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

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

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

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