onCreate — je první a jediná povinná metoda životního cyklu Activity a Fragment v Androidu. Systém ji volá jednou při vytváření komponenty, přičemž předává parametr Bundle s dříve uloženým stavem. Uvnitř onCreate vývojář inicializuje uživatelské rozhraní, váže prvky View, konfiguruje obsluhy událostí a obnovuje data z savedInstanceState. Bez správné implementace onCreate nelze spustit žádnou Android aplikaci — to je vstupní bod pro každou obrazovku. Více o obecném životním cyklu Activity si přečtěte v článku Activity Lifecycle.
Hlavní body
onCreate — metoda zpětného volání (callback), kterou Android volá při vytváření nové instance Activity nebo Fragment. To je první vstupní bod do kódu uživatelské obrazovky: před voláním onCreate se nevykonává žádný uživatelský kód. Systém předává metodě parametr Bundle, který buď obsahuje dříve uložená data (při opětovném vytváření), nebo je null (při prvním spuštění).
Metoda onCreate je definována ve třídě android.app.Activity a ve třídě androidx.fragment.app.Fragment. Obě varianty provádějí podobné úkoly: inicializaci komponenty, konfiguraci UI a obnovení stavu. Konkrétní implementace se však liší — Activity používá setContentView k načtení rozvržení, zatímco Fragment vrací View přes onCreateView. Vývojář je povinen přepsat alespoň onCreate v Activity — bez toho Android nemůže zobrazit obrazovku.
onCreate je volán striktně jednou za celý životní cyklus instance Activity. Dokonce i při otočení obrazovky dostává nová instance Activity nové volání onCreate s Bundle z předchozí instance. Tato vlastnost činí onCreate ideálním místem pro jednorázovou inicializaci: načítání dat, vytváření adaptérů, konfigurace DI komponent přes Dagger nebo Hilt.
V Activity metoda onCreate provádí čtyři klíčové úkoly: načtení rozvržení layout, inicializace prvků View, obnovení stavu z Bundle a konfigurace primárních obsluh událostí. Povinný minimální kód v onCreate — volání super.onCreate(savedInstanceState) a setContentView(R.layout.activity_main).
class MainActivity : AppCompatActivity() {
private var binding: ActivityMainBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ViewBinding — moderní náhrada za findViewById
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding?.root)
// Inicializace pomocí binding
binding?.apply {
welcomeText.text = getString(R.string.welcome)
startButton.setOnClickListener { startGame() }
}
// Obnovení stavu
if (savedInstanceState != null) {
score = savedInstanceState.getInt("score", 0)
binding?.scoreText?.text = score.toString()
}
}
}
Moderní praxe — použití ViewBinding místo findViewById. ViewBinding generuje třídu ActivityMainBinding ve fázi kompilace, což eliminuje chyby s nesprávnými ID a snižuje množství šablonového kódu. Google doporučuje ViewBinding jako standardní způsob přístupu k View v Activity a Fragment od Android Studio 3.6.
Pořadí akcí v onCreate musí být přísné: nejprve super, pak setContentView, poté vše ostatní. Volání findViewById před setContentView vrací null — rozvržení ještě nebylo načteno a prvky View neexistují v hierarchii. To je jedna z nejčastějších chyb začínajících Android vývojářů.
onCreate ve Fragment se liší od Activity: zde se nevolá setContentView, provádí se pouze inicializace dat nesouvisejících s UI. Fragment rozděluje vytváření komponenty a vytváření View do dvou samostatných metod: onCreate (volá se jednou) a onCreateView (volá se pokaždé při vytváření nebo opětovném vytváření View).
class UserListFragment : Fragment() {
private lateinit var viewModel: UserViewModel
private var binding: FragmentUserListBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Inicializace ViewModel — přežije opětovné vytvoření View
viewModel = ViewModelProvider(this)[UserViewModel::class.java]
// Argumenty z FragmentManager
arguments?.let {
viewModel.loadUser(it.getString("user_id") ?: "")
}
// Uložení při otočení
retainInstance = true
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentUserListBinding.inflate(inflater, container, false)
return binding!!.root
}
}
Klíčový rozdíl mezi onCreate Activity a Fragment: onCreate ve Fragment by neměl obsahovat kód související s View, protože View může být zničeno a znovu vytvořeno (například při přepínání karet ViewPager), zatímco onCreate se volá pouze jednou. Načítání dat, konfigurace ViewModel a inicializace adaptérů — úkoly onCreate, zatímco vázání View — úkol onViewCreated.
Parametr savedInstanceState v onCreate — je mechanismus ukládání a obnovování dočasného stavu Activity nebo Fragment. Když systém zničí Activity (otočení obrazovky, nedostatek paměti), zavolá onSaveInstanceState(), do kterého vývojář umístí pár klíč-hodnota do Bundle. Při vytváření nové instance je tento Bundle vrácen v onCreate.
Bundle podporuje následující typy dat: String, Integer, Boolean, Long, Float, Double, jejich pole, stejně jako Parcelable a Serializable objekty. Pro složité objekty se používá Parcelable — efektivnější mechanismus serializace specifický pro Android. Velikost Bundle je omezena přibližně na 500 KB — překročení limitu způsobí výjimku TransactionTooLargeException.
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)
}
Je důležité pochopit: onSaveInstanceState se nevolá, když uživatel explicitně zavře Activity pomocí finish() nebo stisknutím tlačítka „Zpět". Systém předpokládá, že v tomto případě uživatel vědomě ukončuje práci a ukládání stavu není nutné. Proto byste se neměli spoléhat výhradně na savedInstanceState pro dlouhodobé ukládání dat — použijte Room, DataStore nebo SharedPreferences.
onCreate se provádí v hlavním (UI) vlákně a systém čeká na jeho dokončení, než zobrazí Activity na obrazovce. Pokud onCreate trvá déle než 5 sekund, systém zobrazí dialog ANR (Application Not Responding) a navrhne uživateli zavřít aplikaci. Dlouhé operace, jako je načítání dat ze sítě nebo čtení z databáze, by měly být přesunuty do vlákna na pozadí.
Podle doporučení Google Android Performance (2025) by onCreate měl skončit za méně než 1 sekundu na zařízeních střední třídy. K tomu je třeba: používat línou inicializaci (lazy delegát v Kotlin), odložit načítání těžkých dat do onResume nebo přes korutiny, aplikovat ViewStub pro zřídka používané UI komponenty, profilovat čas spuštění přes Android Vitals.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Líná inicializace — objekt se vytváří pouze při prvním přístupu
val heavyData by lazy {
HeavyDataLoader.load()
}
// Načítání dat ve vlákně na pozadí přes lifecycleScope
lifecycleScope.launch(Dispatchers.IO) {
val users = userDao.getAllUsers()
withContext(Dispatchers.Main) {
adapter.submitList(users)
}
}
}
Nástroje profilování: Android Studio Profiler (karta CPU) ukazuje přesný čas provedení každé metody. V Android Vitals (konzole Google Play) můžete sledovat metriku „Čas studeného startu" — pokud onCreate vašeho Activity přesáhne 500 ms, konzole to označí jako problém s výkonem. My v IT Sectr používáme Macrobenchmark testy pro automatickou kontrolu času spuštění každé Activity v CI pipeline.
ViewModel — nejlepší způsob inicializace dat v onCreate, která mají přežít otočení obrazovky. ViewModel se vytváří v onCreate přes ViewModelProvider a automaticky se ukládá při změně konfigurace. Když je Activity po otočení znovu vytvořeno, ViewModel zůstává v paměti a onCreate dostává stejný ViewModel bez ztráty dat.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
// ViewModel se vytváří jednou a přežívá změny konfigurace
val viewModel: ProfileViewModel =
ViewModelProvider(this)[ProfileViewModel::class.java]
// Pozorování LiveData — UI se automaticky aktualizuje při změně dat
viewModel.user.observe(this) { user ->
binding?.userName?.text = user.name
binding?.userEmail?.text = user.email
}
// Načítání dat, pokud byl ViewModel právě vytvořen
if (savedInstanceState == null) {
viewModel.loadProfile(userId)
}
}
Kombinace ViewModel + LiveData/StateFlow řeší problém otočení obrazovky bez ručního ukládání do Bundle. ViewModel ukládá data v paměti, LiveData automaticky znovu přihlašuje Activity při opětovném vytvoření a StateFlow (z Kotlin Coroutines) přidává reaktivitu s podporou korutin. Toto je standardní architektura doporučená Googlem v průvodci Guide to App Architecture.
Dokonce i zkušení vývojáři dělají typické chyby v onCreate. Pojďme se podívat na pět nejčastějších problémů a způsoby, jak se jim vyhnout.
Nejčastější chyba — pokus o nalezení View pomocí findViewById před voláním setContentView. Všechny prvky View se vytvářejí v okamžiku nafouknutí rozvržení, takže jakýkoli odkaz na findViewById před setContentView vrací null a způsobí NullPointerException při pokusu o použití View. Řešení: přísné pořadí — nejprve super, pak setContentView, poté findViewById nebo ViewBinding.
Načítání dat ze sítě, čtení z databáze nebo zpracování velkých polí přímo v onCreate blokuje vykreslení prvního snímku. Uživatel vidí černou obrazovku, dokud onCreate neskončí, což zhoršuje vnímání rychlosti aplikace. Řešení: používejte lifecycleScope.launch pro asynchronní operace, zobrazte kostru (placeholder UI) do dokončení načítání.
Pokud se při otočení obrazovky neobnoví stav z Bundle, uživatel ztratí všechny neuložené vstupy: text v polích formuláře, pozici posouvání, vybrané prvky. Řešení: vždy kontrolujte savedInstanceState != null v onCreate pro obnovení dat, i když se ztráta stavu zdá nepravděpodobná.
Anonymní třídy a lambdy v onCreate mohou implicitně držet odkaz na Activity po jeho zničení. Například Handler vytvořený v onCreate pokračuje v provádění odložených úkolů i poté, co je Activity zničeno. Řešení: používejte LifecycleObserver, ViewModel a lifecycleScope, které automaticky ruší úkoly při zničení.
Inicializace View v onCreate Fragment — logická chyba, protože View může být znovu vytvořeno bez volání onCreate. Pokud je posluchač nastaven v onCreate a View je svázáno v onCreateView, při opětovném vytvoření posluchač zůstane na starém View. Řešení: veškerou práci s View provádějte v onViewCreated, onCreate ponechte pouze pro inicializaci datové vrstvy.
Často kladené otázky
Ano, přepsání onCreate je povinné pro každé Activity, které zobrazuje uživatelské rozhraní. Bez toho nelze zavolat setContentView a načíst XML rozvržení. Pokud Activity nemá UI (například průhledné Activity-zástupka), onCreate se stejně přepisuje, ale bez volání setContentView.
Ne, onCreate nemůže být znovu zavolán pro stejnou instanci Activity. Pokud je Activity zničeno a znovu vytvořeno (otočení obrazovky, nedostatek paměti), je to již nová instance s novým voláním onCreate. Výjimka — metoda recreate(), která vynutí zničení a opětovné vytvoření Activity, ale to je také vytvoření nové instance.
Pokud se nezavolá super.onCreate(savedInstanceState), Android Runtime vyhodí výjimku SuperNotCalledException a aplikace spadne. Systém přísně vyžaduje, aby každá přepsaná metoda životního cyklu volala svou super verzi — to zaručuje správnou funkci interního stavového automatu.
Hlavní rozdíl: onCreate v Activity načítá UI přes setContentView, zatímco onCreate ve Fragment pouze inicializuje data. Fragment vytváří View v samostatné metodě onCreateView, která může být volána vícekrát (například při přepínání karet), zatímco onCreate Fragment je volán jednou za dobu životnosti instance Fragment.
Data inicializovaná v onCreate se ukládají do polí třídy Activity nebo Fragment. Například private lateinit var binding: ActivityMainBinding se deklaruje na úrovni třídy, inicializuje v onCreate a je přístupné ve všech následujících metodách. Pro data, která přežijí otočení obrazovky, použijte ViewModel s LiveData nebo StateFlow.
Shrnutí
Vyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také