onCreate — co to, inicjalizacja Activity w Android

Autor: IT Sectr Opublikowano: 2026-03-03 Czas czytania: 10 min

onCreate — to pierwsza i jedyna obowiązkowa metoda cyklu życia Activity i Fragment w Android. System wywołuje ją raz przy tworzeniu komponentu, przekazując parametr Bundle z wcześniej zapisanym stanem. Wewnątrz onCreate programista inicjalizuje interfejs użytkownika, wiąże elementy View, konfiguruje procedury obsługi zdarzeń i przywraca dane z savedInstanceState. Bez poprawnej implementacji onCreate nie można uruchomić żadnej aplikacji Android — to punkt wejścia dla każdego ekranu. Więcej o ogólnym cyklu życia Activity przeczytasz w artykule Activity Lifecycle.

Najważniejsze

  • onCreate — pierwsza i jedyna obowiązkowa metoda cyklu życia; wywoływana raz przy tworzeniu Activity lub Fragment
  • Parametr Bundle — savedInstanceState zawiera dane zapisane w onSaveInstanceState lub null, jeśli Activity jest tworzone po raz pierwszy
  • setContentView — obowiązkowe wywołanie wewnątrz onCreate dla Activity; łączy układ XML z kodem
  • Inicjalizacja UI — findViewById, konfiguracja adapterów RecyclerView, ustawianie nasłuchiwaczy kliknięć — typowe zadania onCreate
  • Fragment.onCreate — różni się od Activity: tutaj nie wywołuje się setContentView, a układ przekazuje się przez onCreateView
  • Ograniczenie czasowe — onCreate musi zakończyć się w ciągu 5 sekund (próg ANR), długotrwałe operacje przenosi się do wątku tła
  • ViewModel i onCreate — inicjalizacja ViewModel w onCreate pozwala danym przetrwać obrót ekranu bez utraty

Czym jest onCreate w Android

onCreate — metoda zwrotna (callback), którą Android wywołuje przy tworzeniu nowego egzemplarza Activity lub Fragment. To pierwszy punkt wejścia do kodu ekranu użytkownika: przed wywołaniem onCreate żaden kod użytkownika nie jest wykonywany. System przekazuje do metody parametr Bundle, który albo zawiera wcześniej zapisane dane (przy ponownym tworzeniu), albo jest równy null (przy pierwszym uruchomieniu).

Metoda onCreate jest zdefiniowana w klasie android.app.Activity i w klasie androidx.fragment.app.Fragment. Obie wersje wykonują podobne zadania: inicjalizacja komponentu, konfiguracja UI i przywracanie stanu. Jednak konkretna implementacja różni się — Activity używa setContentView do załadowania układu, a Fragment zwraca View przez onCreateView. Programista musi nadpisać przynajmniej onCreate w Activity — bez tego Android nie będzie mógł wyświetlić ekranu.

onCreate jest wywoływany ściśle raz na pełny cykl życia egzemplarza Activity. Nawet przy obrocie ekranu nowy egzemplarz Activity otrzymuje nowe wywołanie onCreate z Bundle od poprzedniego egzemplarza. Ta właściwość czyni onCreate idealnym miejscem do jednorazowej inicjalizacji: ładowanie danych, tworzenie adapterów, konfiguracja komponentów DI przez Dagger lub Hilt.

onCreate w Activity

W Activity metoda onCreate wykonuje cztery kluczowe zadania: ładowanie układu layout, inicjalizacja elementów View, przywracanie stanu z Bundle i konfiguracja podstawowych procedur obsługi zdarzeń. Obowiązkowy minimalny kod w onCreate — wywołanie super.onCreate(savedInstanceState) i setContentView(R.layout.activity_main).

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

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

        // ViewBinding — nowoczesny zamiennik findViewById
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding?.root)

        // Inicjalizacja za pomocą binding
        binding?.apply {
            welcomeText.text = getString(R.string.welcome)
            startButton.setOnClickListener { startGame() }
        }

        // Przywracanie stanu
        if (savedInstanceState != null) {
            score = savedInstanceState.getInt("score", 0)
            binding?.scoreText?.text = score.toString()
        }
    }
}

Nowoczesna praktyka — użycie ViewBinding zamiast findViewById. ViewBinding generuje klasę ActivityMainBinding na etapie kompilacji, co eliminuje błędy z nieprawidłowymi ID i zmniejsza ilość kodu szablonowego. Google zaleca ViewBinding jako standardowy sposób dostępu do View w Activity i Fragment od Android Studio 3.6.

Kolejność działań w onCreate musi być ścisła: najpierw super, potem setContentView, następnie wszystko inne. Wywołanie findViewById przed setContentView zwróci null — układ nie został jeszcze załadowany, a elementy View nie istnieją w hierarchii. To jeden z najczęstszych błędów początkujących programistów Android.

onCreate we Fragment

onCreate we Fragment różni się od Activity: tutaj nie wywołuje się setContentView, a wykonuje się tylko inicjalizację danych niezwiązanych z UI. Fragment dzieli tworzenie komponentu i tworzenie View na dwie osobne metody: onCreate (wywoływana raz) i onCreateView (wywoływana za każdym razem przy tworzeniu lub ponownym tworzeniu View).

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

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

        // Inicjalizacja ViewModel — przetrwa ponowne utworzenie View
        viewModel = ViewModelProvider(this)[UserViewModel::class.java]

        // Argumenty z FragmentManager
        arguments?.let {
            viewModel.loadUser(it.getString("user_id") ?: "")
        }

        // Zachowanie przy obrocie
        retainInstance = true
    }

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

Kluczowa różnica między onCreate Activity i Fragment: onCreate we Fragment nie powinien zawierać kodu związanego z View, ponieważ View może być zniszczony i utworzony ponownie (na przykład przy przełączaniu zakładek ViewPager), a onCreate jest wywoływany tylko raz. Ładowanie danych, konfiguracja ViewModel i inicjalizacja adapterów — zadania onCreate, a wiązanie View — zadanie onViewCreated.

savedInstanceState i przywracanie stanu

Parametr savedInstanceState w onCreate — to mechanizm zapisywania i przywracania tymczasowego stanu Activity lub Fragment. Gdy system niszczy Activity (obrót ekranu, brak pamięci), wywołuje onSaveInstanceState(), do którego programista umieszcza parę klucz-wartość w Bundle. Przy tworzeniu nowego egzemplarza ten Bundle jest zwracany w onCreate.

Bundle obsługuje następujące typy danych: String, Integer, Boolean, Long, Float, Double, ich tablice, a także obiekty Parcelable i Serializable. Dla złożonych obiektów używa się Parcelable — to bardziej wydajny mechanizm serializacji, specyficzny dla Android. Rozmiar Bundle jest ograniczony do około 500 KB — przekroczenie limitu powoduje wyjątek 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)
}

Ważne jest zrozumienie: onSaveInstanceState nie jest wywoływane, gdy użytkownik jawnie zamyka Activity przez finish() lub naciśnięcie przycisku „Wstecz"). System uważa, że w tym przypadku użytkownik świadomie kończy pracę i zapisywanie stanu nie jest wymagane. Dlatego poleganie wyłącznie na savedInstanceState do długoterminowego przechowywania danych jest niewłaściwe — używaj Room, DataStore lub SharedPreferences.

Czasy i ograniczenia onCreate

onCreate jest wykonywany w głównym (UI) wątku, a system czeka na jego zakończenie, zanim wyświetli Activity na ekranie. Jeśli onCreate wykonuje się dłużej niż 5 sekund, system pokazuje okno dialogowe ANR (Application Not Responding) i proponuje użytkownikowi zamknięcie aplikacji. Długotrwałe operacje, takie jak ładowanie danych z sieci lub odczyt z bazy danych, powinny być przeniesione do wątku tła.

Zgodnie z zaleceniami Google Android Performance (2025), onCreate powinien zakończyć się w mniej niż 1 sekundę na urządzeniach średniej klasy. W tym celu należy: używać leniwej inicjalizacji (lazy delegate w Kotlin), odłożyć ładowanie ciężkich danych do onResume lub przez korutyny, stosować ViewStub dla rzadko używanych komponentów UI, profilować czas uruchamiania przez Android Vitals.

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

    // Leniiwa inicjalizacja — obiekt tworzony tylko przy pierwszym dostępie
    val heavyData by lazy {
        HeavyDataLoader.load()
    }

    // Ładowanie danych w wątku tła przez lifecycleScope
    lifecycleScope.launch(Dispatchers.IO) {
        val users = userDao.getAllUsers()
        withContext(Dispatchers.Main) {
            adapter.submitList(users)
        }
    }
}

Narzędzia profilowania: Android Studio Profiler (zakładka CPU) pokazuje dokładny czas wykonania każdej metody. W Android Vitals (konsola Google Play) można śledzić metrykę „Czas zimnego startu") — jeśli onCreate twojego Activity przekracza 500 ms, konsola oznacza to jako problem wydajności. My w IT Sectr używamy testów Macrobenchmark do automatycznej kontroli czasu uruchamiania każdej Activity w CI-pipeline.

ViewModel i onCreate

ViewModel — najlepszy sposób inicjalizacji danych w onCreate, które powinny przetrwać obrót ekranu. ViewModel jest tworzony w onCreate przez ViewModelProvider i automatycznie zachowywany przy zmianie konfiguracji. Gdy Activity jest ponownie tworzone po obrocie, ViewModel pozostaje w pamięci, a onCreate otrzymuje ten sam ViewModel bez utraty danych.

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

    // ViewModel tworzony raz i przetrwa zmiany konfiguracji
    val viewModel: ProfileViewModel =
        ViewModelProvider(this)[ProfileViewModel::class.java]

    // Obserwacja LiveData — UI automatycznie aktualizuje się przy zmianie danych
    viewModel.user.observe(this) { user ->
        binding?.userName?.text = user.name
        binding?.userEmail?.text = user.email
    }

    // Ładowanie danych, jeśli ViewModel właśnie został utworzony
    if (savedInstanceState == null) {
        viewModel.loadProfile(userId)
    }
}

Kombinacja ViewModel + LiveData/StateFlow rozwiązuje problem obrotu ekranu bez ręcznego zapisywania w Bundle. ViewModel przechowuje dane w pamięci, LiveData automatycznie ponownie subskrybuje Activity przy ponownym tworzeniu, a StateFlow (z Kotlin Coroutines) dodaje reaktywność z obsługą korutyn. To standardowa architektura zalecana przez Google w przewodniku Guide to App Architecture.

Częste błędy przy pracy z onCreate

Nawet doświadczeni programiści popełniają typowe błędy w onCreate. Omówmy pięć najczęstszych problemów i sposoby ich unikania.

Praca z View przed setContentView

Najczęstszy błąd — próba znalezienia View przez findViewById przed wywołaniem setContentView. Wszystkie elementy View są tworzone w momencie inflacji układu, więc każde odwołanie do findViewById przed setContentView zwraca null i powoduje NullPointerException przy próbie użycia View. Rozwiązanie: ścisła kolejność — najpierw super, potem setContentView, następnie findViewById lub ViewBinding.

Blokowanie wątku UI długotrwałymi operacjami

Ładowanie danych z sieci, odczyt z bazy danych lub przetwarzanie dużych tablic bezpośrednio w onCreate blokuje renderowanie pierwszej klatki. Użytkownik widzi czarny ekran, dopóki onCreate się nie zakończy, co pogarsza postrzeganie szybkości działania aplikacji. Rozwiązanie: używać lifecycleScope.launch do operacji asynchronicznych, wyświetlać szkielet (placeholder UI) do czasu zakończenia ładowania.

Ignorowanie savedInstanceState

Jeśli przy obrocie ekranu nie przywraca się stanu z Bundle, użytkownik traci cały niezapisany wkład: tekst w polach formularza, pozycję scrolla, wybrane elementy. Rozwiązanie: zawsze sprawdzać savedInstanceState != null w onCreate do przywracania danych, nawet jeśli wydaje się, że utrata stanu jest mało prawdopodobna.

Wyciek pamięci przez anonimowe klasy

Anonimowe klasy i lambdy w onCreate mogą niejawnie utrzymywać referencję do Activity po jego zniszczeniu. Na przykład Handler utworzony w onCreate kontynuuje wykonywanie odroczonych zadań nawet po zniszczeniu Activity. Rozwiązanie: używać LifecycleObserver, ViewModel i lifecycleScope, które automatycznie anulują zadania przy zniszczeniu.

Nadmierna inicjalizacja w onCreate Fragment

Inicjalizacja View w onCreate Fragment — błąd logiczny, ponieważ View może być ponownie utworzone bez wywołania onCreate. Jeśli ustawi się nasłuchiwacza w onCreate, a View wiąże się w onCreateView, przy ponownym tworzeniu nasłuchiwacz pozostanie na starym View. Rozwiązanie: całą pracę z View wykonywać w onViewCreated, a onCreate pozostawić tylko do inicjalizacji warstwy danych.

Często zadawane pytania

Czy konieczne jest nadpisywanie onCreate w Activity?

Tak, nadpisywanie onCreate jest obowiązkowe dla każdej Activity, która wyświetla interfejs użytkownika. Bez tego nie można wywołać setContentView i załadować układu XML. Jeśli Activity nie ma UI (na przykład przezroczysta Activity-zastawka), onCreate i tak jest nadpisywane, ale bez wywołania setContentView.

Czy onCreate może być wywołany ponownie bez niszczenia Activity?

Nie, onCreate nie może być wywołany ponownie dla tego samego egzemplarza Activity. Jeśli Activity jest zniszczona i utworzona na nowo (obrót ekranu, brak pamięci), to już nowy egzemplarz z nowym wywołaniem onCreate. Wyjątek — metoda recreate(), która wymusza zniszczenie i ponowne utworzenie Activity, ale to jest ponowne utworzenie nowego egzemplarza.

Co się stanie, jeśli nie wywoła się super.onCreate?

Jeśli nie wywołasz super.onCreate(savedInstanceState), Android Runtime wyrzuci wyjątek SuperNotCalledException i aplikacja ulegnie awarii. System ściśle wymaga, aby każda nadpisana metoda cyklu życia wywoływała swoją super-wersję — gwarantuje to poprawne działanie wewnętrznego automatu stanów.

Czym różni się onCreate w Activity od onCreate we Fragment?

Główna różnica: onCreate w Activity ładuje UI przez setContentView, a onCreate we Fragment tylko inicjalizuje dane. Fragment tworzy View w osobnej metodzie onCreateView, która może być wywoływana wielokrotnie (na przykład przy przełączaniu zakładek), podczas gdy onCreate Fragment jest wywoływany raz na czas życia egzemplarza Fragment.

Jak przekazać dane z onCreate do innych metod?

Dane zainicjalizowane w onCreate przechowuje się w polach klasy Activity lub Fragment. Na przykład private lateinit var binding: ActivityMainBinding jest deklarowane na poziomie klasy, inicjalizowane w onCreate i dostępne we wszystkich kolejnych metodach. Dla danych przetrwających obrót ekranu używa się ViewModel z LiveData lub StateFlow.

Podsumowanie

  • onCreate — obowiązkowa metoda cyklu życia, wywoływana raz przy tworzeniu Activity lub Fragment
  • setContentView — obowiązkowe wywołanie dla Activity, ładuje układ XML; dla Fragment układ ładuje się przez onCreateView
  • savedInstanceState — Bundle z zapisanym stanem przy ponownym tworzeniu; null przy pierwszym uruchomieniu
  • Ograniczenie czasowe — onCreate powinien wykonać się w mniej niż 1 sekundę, długotrwałe operacje przenosi się do korutyn
  • ViewModel — inicjalizacja ViewModel w onCreate rozwiązuje problem utraty danych przy obrocie ekranu
  • Fragment vs Activity — onCreate Fragment nie zawiera kodu UI, onCreate Activity ładuje układ przez setContentView
  • Pięć typowych błędów — praca z View przed setContentView, blokowanie UI, ignorowanie Bundle, wycieki pamięci, kod UI w Fragment.onCreate

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również