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 для асинхронных операций, отображать скелетон (placeholder UI) до завершения загрузки.

Игнорирование savedInstanceState

Если при повороте экрана не восстанавливать состояние из Bundle, пользователь теряет весь несохранённый ввод: текст в полях формы, позицию скролла, выбранные элементы. Решение: всегда проверять savedInstanceState != null в onCreate для восстановления данных, даже если кажется, что потеря состояния маловероятна.

Утечка памяти через анонимные классы

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

Чрезмерная инициализация в onCreate Fragment

Инициализация View в onCreate Fragment — логическая ошибка, так как View может быть пересоздан без вызова onCreate. Если установить слушателя в onCreate, а View привязывать в onCreateView, при пересоздании слушатель останется на старом View. Решение: всю работу с View выполнять в onViewCreated, а onCreate оставлять только для инициализации data-слоя.

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

Обязательно ли переопределять 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 — onCreate Fragment не содержит UI-код, onCreate Activity загружает разметку через setContentView
  • Пять типовых ошибок — работа с View до setContentView, блокировка UI, игнорирование Bundle, утечки памяти, UI-код в Fragment.onCreate

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

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

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

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