onCreate ist die erste und einzige obligatorische Methode des Activity- und Fragment-Lebenszyklus in Android. Das System ruft sie einmal beim Erstellen einer Komponente auf und übergibt den Bundle-Parameter mit dem zuvor gespeicherten Zustand. Innerhalb von onCreate initialisiert der Entwickler die Benutzeroberfläche, bindet View-Elemente, konfiguriert Ereignisbehandler und stellt Daten aus savedInstanceState wieder her. Ohne eine korrekte Implementierung von onCreate kann keine Android-Anwendung gestartet werden — es ist der Einstiegspunkt für jeden Bildschirm. Weitere Informationen zum allgemeinen Activity-Lebenszyklus finden Sie im Artikel Activity Lifecycle.
Wichtige Erkenntnisse
onCreate ist eine Callback-Methode, die Android beim Erstellen einer neuen Instanz einer Activity oder eines Fragments aufruft. Dies ist der erste Einstiegspunkt in den Benutzerbildschirmcode: Vor dem Aufruf von onCreate wird kein Benutzercode ausgeführt. Das System übergibt einen Bundle-Parameter an die Methode, der entweder zuvor gespeicherte Daten (bei Neuerstellung) oder null (beim ersten Start) enthält.
Die onCreate-Methode ist in der Klasse android.app.Activity und in der Klasse androidx.fragment.app.Fragment definiert. Beide Varianten führen ähnliche Aufgaben aus: Komponenteninitialisierung, UI-Einrichtung und Zustandswiederherstellung. Die spezifische Implementierung unterscheidet sich jedoch — Activity verwendet setContentView zum Laden des Layouts, während Fragment eine View über onCreateView zurückgibt. Der Entwickler muss mindestens onCreate in Activity überschreiben — ohne dies kann Android den Bildschirm nicht anzeigen.
onCreate wird strikt einmal pro vollständigem Lebenszyklus einer Activity-Instanz aufgerufen. Selbst bei Bildschirmdrehung erhält eine neue Activity-Instanz einen neuen onCreate-Aufruf mit dem Bundle der vorherigen Instanz. Dies macht onCreate zum idealen Ort für einmalige Initialisierungen: Laden von Daten, Erstellen von Adaptern, Einrichten von DI-Komponenten über Dagger oder Hilt.
In Activity führt die onCreate-Methode vier Hauptaufgaben aus: Laden des Layouts, Initialisieren der View-Elemente, Wiederherstellen des Zustands aus Bundle und Einrichten der primären Ereignisbehandler. Der obligatorische Mindestcode in onCreate ist der Aufruf von super.onCreate(savedInstanceState) und setContentView(R.layout.activity_main).
class MainActivity : AppCompatActivity() {
private var binding: ActivityMainBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ViewBinding — ein moderner Ersatz für findViewById
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding?.root)
// Initialisierung mit Binding
binding?.apply {
welcomeText.text = getString(R.string.welcome)
startButton.setOnClickListener { startGame() }
}
// Wiederherstellung des Zustands
if (savedInstanceState != null) {
score = savedInstanceState.getInt("score", 0)
binding?.scoreText?.text = score.toString()
}
}
}
Die moderne Praxis verwendet ViewBinding anstelle von findViewById. ViewBinding generiert die Klasse ActivityMainBinding zur Kompilierzeit, wodurch Fehler durch falsche IDs vermieden und Boilerplate-Code reduziert werden. Google empfiehlt ViewBinding ab Android Studio 3.6 als Standardmethode für den Zugriff auf View in Activity und Fragment.
Die Reihenfolge der Operationen in onCreate muss streng sein: zuerst super, dann setContentView, dann alles andere. Ein Aufruf von findViewById vor setContentView gibt null zurück — das Layout wurde noch nicht geladen und die View-Elemente existieren nicht in der Hierarchie. Dies ist einer der häufigsten Fehler von Android-Anfängern.
onCreate in Fragment unterscheidet sich von Activity: hier wird setContentView nicht aufgerufen, es wird nur die Initialisierung von Daten durchgeführt, die nicht mit der UI zusammenhängen. Fragment trennt die Komponentenerstellung und die View-Erstellung in zwei separate Methoden: onCreate (einmal aufgerufen) und onCreateView (jedes Mal aufgerufen, wenn die View erstellt oder neu erstellt wird).
class UserListFragment : Fragment() {
private lateinit var viewModel: UserViewModel
private var binding: FragmentUserListBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ViewModel-Initialisierung — überlebt die View-Neuerstellung
viewModel = ViewModelProvider(this)[UserViewModel::class.java]
// Argumente von FragmentManager
arguments?.let {
viewModel.loadUser(it.getString("user_id") ?: "")
}
// Speichern bei Drehung
retainInstance = true
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentUserListBinding.inflate(inflater, container, false)
return binding!!.root
}
}
Der Hauptunterschied zwischen Activity- und Fragment-onCreate: onCreate in Fragment sollte keinen Code enthalten, der sich auf View bezieht, weil die View zerstört und neu erstellt werden kann (z.B. beim Wechseln von ViewPager-Tabs), während onCreate nur einmal aufgerufen wird. Daten laden, ViewModel einrichten und Adapter initialisieren sind Aufgaben von onCreate, während das Binden von View eine Aufgabe von onViewCreated ist.
Der savedInstanceState-Parameter in onCreate ist ein Mechanismus zum Speichern und Wiederherstellen des temporären Zustands einer Activity oder eines Fragments. Wenn das System eine Activity zerstört (Bildschirmdrehung, Speichermangel), ruft es onSaveInstanceState() auf, in das der Entwickler Schlüssel-Wert-Einträge in ein Bundle einfügt. Wenn eine neue Instanz erstellt wird, wird dieses Bundle in onCreate zurückgegeben.
Bundle unterstützt die folgenden Datentypen: String, Integer, Boolean, Long, Float, Double, deren Arrays sowie Parcelable- und Serializable-Objekte. Für komplexe Objekte wird Parcelable verwendet — ein effizienterer Serialisierungsmechanismus, der für Android spezifisch ist. Die Bundle-Größe ist auf etwa 500 KB begrenzt — eine Überschreitung des Limits führt zu einer 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)
}
Es ist wichtig zu verstehen: onSaveInstanceState wird nicht aufgerufen, wenn der Benutzer die Activity explizit über finish() oder die Zurück-Taste schließt. Das System geht davon aus, dass der Benutzer die Arbeit bewusst beendet und den Zustand nicht speichern muss. Daher kann man sich für die langfristige Datenspeicherung nicht ausschließlich auf savedInstanceState verlassen — verwenden Sie Room, DataStore oder SharedPreferences.
onCreate wird im Haupt- (UI-) Thread ausgeführt, und das System wartet auf dessen Abschluss, bevor es die Activity auf dem Bildschirm anzeigt. Wenn onCreate länger als 5 Sekunden dauert, zeigt das System einen ANR-Dialog (Application Not Responding) an und bietet dem Benutzer die Möglichkeit, die Anwendung zu schließen. Lange Operationen wie das Laden von Daten aus dem Netzwerk oder das Lesen aus einer Datenbank müssen in einen Hintergrundthread verschoben werden.
Gemäß den Empfehlungen von Google Android Performance (2025) sollte onCreate auf Mittelklassegeräten in weniger als 1 Sekunde abgeschlossen sein. Um dies zu erreichen: Verwenden Sie verzögerte Initialisierung (lazy-Delegat in Kotlin), verschieben Sie das Laden schwerer Daten auf onResume oder über Coroutinen, wenden Sie ViewStub für selten verwendete UI-Komponenten an und profilieren Sie die Startzeit über Android Vitals.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Faule Initialisierung — Objekt wird nur beim ersten Zugriff erstellt
val heavyData by lazy {
HeavyDataLoader.load()
}
// Daten im Hintergrundthread über lifecycleScope laden
lifecycleScope.launch(Dispatchers.IO) {
val users = userDao.getAllUsers()
withContext(Dispatchers.Main) {
adapter.submitList(users)
}
}
}
Profiling-Tools: Android Studio Profiler (CPU-Tab) zeigt die genaue Ausführungszeit jeder Methode. In Android Vitals (Google Play Console) können Sie die Metrik „Kaltstartzeit“ verfolgen — wenn Ihr Activity-onCreate 500 ms überschreitet, markiert die Konsole dies als Leistungsproblem. Bei IT Sectr verwenden wir Macrobenchmark-Tests zur automatischen Überwachung der Startzeit jeder Activity in der CI-Pipeline.
ViewModel ist die beste Möglichkeit, Daten in onCreate zu initialisieren, die eine Bildschirmdrehung überstehen sollen. ViewModel wird in onCreate über ViewModelProvider erstellt und bei Konfigurationsänderungen automatisch beibehalten. Wenn eine Activity nach einer Drehung neu erstellt wird, bleibt ViewModel im Speicher und onCreate erhält dasselbe ViewModel ohne Datenverlust.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
// ViewModel wird einmal erstellt und überlebt Konfigurationsänderungen
val viewModel: ProfileViewModel =
ViewModelProvider(this)[ProfileViewModel::class.java]
// LiveData-Beobachtung — UI wird automatisch aktualisiert, wenn sich Daten ändern
viewModel.user.observe(this) { user ->
binding?.userName?.text = user.name
binding?.userEmail?.text = user.email
}
// Daten laden, wenn ViewModel gerade erstellt wurde
if (savedInstanceState == null) {
viewModel.loadProfile(userId)
}
}
Die Kombination von ViewModel + LiveData/StateFlow löst das Problem der Bildschirmdrehung ohne manuelles Speichern in Bundle. ViewModel speichert Daten im Speicher, LiveData abonniert die Activity bei Neuerstellung automatisch neu, und StateFlow (aus Kotlin Coroutines) fügt Reaktivität mit Coroutine-Unterstützung hinzu. Dies ist die von Google im Guide to App Architecture empfohlene Standardarchitektur.
Sogar erfahrene Entwickler machen typische Fehler in onCreate. Betrachten wir die fünf häufigsten Probleme und wie man sie vermeidet.
Der häufigste Fehler ist der Versuch, eine View über findViewById vor dem Aufruf von setContentView zu finden. Alle View-Elemente werden zum Zeitpunkt der Layout-Inflation erstellt, daher gibt jeder findViewById-Aufruf vor setContentView null zurück und verursacht eine NullPointerException beim Versuch, die View zu verwenden. Lösung: strenge Reihenfolge — zuerst super, dann setContentView, dann findViewById oder ViewBinding.
Das Laden von Daten aus dem Netzwerk, das Lesen aus einer Datenbank oder die Verarbeitung großer Arrays direkt in onCreate blockiert das Rendern des ersten Frames. Der Benutzer sieht einen schwarzen Bildschirm, bis onCreate abgeschlossen ist, was die Wahrnehmung der Anwendungsgeschwindigkeit beeinträchtigt. Lösung: Verwenden Sie lifecycleScope.launch für asynchrone Operationen, zeigen Sie ein Skelett (Platzhalter-UI) an, bis der Ladevorgang abgeschlossen ist.
Wenn Sie bei Bildschirmdrehung den Zustand nicht aus Bundle wiederherstellen, verliert der Benutzer alle nicht gespeicherten Eingaben: Text in Formularfeldern, Bildlaufposition, ausgewählte Elemente. Lösung: Überprüfen Sie immer savedInstanceState != null in onCreate, um Daten wiederherzustellen, auch wenn ein Zustandsverlust unwahrscheinlich erscheint.
Anonyme Klassen und Lambdas in onCreate können implizit einen Verweis auf eine Activity halten, nachdem diese zerstört wurde. Beispielsweise führt ein in onCreate erstellter Handler weiterhin verzögerte Aufgaben aus, selbst nachdem die Activity zerstört wurde. Lösung: Verwenden Sie LifecycleObserver, ViewModel und lifecycleScope, die Aufgaben bei Zerstörung automatisch abbrechen.
Die Initialisierung von View in Fragment.onCreate ist ein logischer Fehler, da die View ohne Aufruf von onCreate neu erstellt werden kann. Wenn Sie einen Listener in onCreate setzen, aber View in onCreateView binden, bleibt der Listener bei Neuerstellung an der alten View haften. Lösung: Führen Sie alle View-bezogenen Arbeiten in onViewCreated durch und lassen Sie onCreate nur für die Initialisierung der Datenschicht übrig.
Häufig gestellte Fragen
Ja, das Überschreiben von onCreate ist obligatorisch für jede Activity, die eine Benutzeroberfläche anzeigt. Ohne dies ist es unmöglich, setContentView aufzurufen und das XML-Layout zu laden. Wenn die Activity keine UI hat (z.B. eine transparente Activity-Stub), wird onCreate trotzdem überschrieben, aber ohne setContentView aufzurufen.
Nein, onCreate kann nicht erneut für dieselbe Activity-Instanz aufgerufen werden. Wenn eine Activity zerstört und neu erstellt wird (Bildschirmdrehung, Speichermangel), ist es eine neue Instanz mit einem neuen Aufruf von onCreate. Eine Ausnahme ist die recreate()-Methode, die die Activity zwangsweise zerstört und neu erstellt, aber dies ist eine Neuerstellung einer neuen Instanz.
Wenn Sie super.onCreate(savedInstanceState) nicht aufrufen, wirft die Android Runtime eine SuperNotCalledException und die Anwendung stürzt ab. Das System verlangt strikt, dass jede überschriebene Lebenszyklusmethode ihre Super-Version aufruft — dies gewährleistet den korrekten Betrieb der internen Zustandsmaschine.
Der Hauptunterschied: onCreate in Activity lädt die UI über setContentView, während onCreate in Fragment nur Daten initialisiert. Fragment erstellt die View in einer separaten Methode onCreateView, die mehrmals aufgerufen werden kann (z.B. beim Wechseln von Tabs), während Fragment onCreate einmal pro Fragment-Instanzlebensdauer aufgerufen wird.
In onCreate initialisierte Daten werden in den Klassenfeldern der Activity oder des Fragments gespeichert. Beispielsweise wird private lateinit var binding: ActivityMainBinding auf Klassenebene deklariert, in onCreate initialisiert und ist in allen nachfolgenden Methoden verfügbar. Für Daten, die eine Bildschirmdrehung überstehen sollen, verwenden Sie ViewModel mit LiveData oder StateFlow.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch