onCreate — is de eerste en enige verplichte methode van de levenscyclus van Activity en Fragment in Android. Het systeem roept deze eenmalig aan bij het aanmaken van de component, waarbij de parameter Bundle met de eerder opgeslagen toestand wordt doorgegeven. Binnenin onCreate initialiseert de ontwikkelaar de gebruikersinterface, koppelt View-elementen, configureert gebeurtenisafhandelaars en herstelt gegevens uit savedInstanceState. Zonder een correcte implementatie van onCreate kan geen enkele Android-app worden gestart — het is het toegangspunt voor elk scherm. Lees meer over de algemene levenscyclus van Activity in het artikel Activity Lifecycle.
Belangrijkste punten
onCreate — een callback-methode die Android aanroept bij het aanmaken van een nieuwe instantie van Activity of Fragment. Dit is het eerste toegangspunt tot de code van het gebruikersscherm: vóór de aanroep van onCreate wordt geen gebruikerscode uitgevoerd. Het systeem geeft de parameter Bundle door aan de methode, die ofwel eerder opgeslagen gegevens bevat (bij herbouw) ofwel null is (bij de eerste start).
De methode onCreate is gedefinieerd in de klasse android.app.Activity en in de klasse androidx.fragment.app.Fragment. Beide varianten voeren vergelijkbare taken uit: initialisatie van de component, configuratie van de UI en herstel van de toestand. De specifieke implementatie verschilt echter — Activity gebruikt setContentView om de layout te laden, terwijl Fragment View retourneert via onCreateView. De ontwikkelaar is verplicht om ten minste onCreate in Activity te overschrijven — zonder dit kan Android het scherm niet weergeven.
onCreate wordt strikt eenmalig aangeroepen gedurende de volledige levenscyclus van de Activity-instantie. Zelfs bij schermrotatie krijgt de nieuwe Activity-instantie een nieuwe onCreate-aanroep met de Bundle van de vorige instantie. Deze eigenschap maakt onCreate de ideale plek voor eenmalige initialisatie: het laden van gegevens, het aanmaken van adapters, het configureren van DI-componenten via Dagger of Hilt.
In Activity voert de methode onCreate vier kerntaken uit: het laden van de layout, initialisatie van View-elementen, herstel van de toestand uit Bundle en configuratie van primaire gebeurtenisafhandelaars. De verplichte minimale code in onCreate — aanroep van super.onCreate(savedInstanceState) en setContentView(R.layout.activity_main).
class MainActivity : AppCompatActivity() {
private var binding: ActivityMainBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ViewBinding — moderne vervanger van findViewById
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding?.root)
// Initialisatie met behulp van binding
binding?.apply {
welcomeText.text = getString(R.string.welcome)
startButton.setOnClickListener { startGame() }
}
// Toestandsherstel
if (savedInstanceState != null) {
score = savedInstanceState.getInt("score", 0)
binding?.scoreText?.text = score.toString()
}
}
}
Moderne praktijk — gebruik van ViewBinding in plaats van findViewById. ViewBinding genereert de klasse ActivityMainBinding tijdens de compilatiefase, wat fouten met onjuiste ID's elimineert en de hoeveelheid sjablooncode vermindert. Google beveelt ViewBinding aan als standaardmanier om toegang te krijgen tot View in Activity en Fragment vanaf Android Studio 3.6.
De volgorde van acties in onCreate moet strikt zijn: eerst super, dan setContentView, daarna al het andere. Het aanroepen van findViewById vóór setContentView retourneert null — de layout is nog niet geladen en de View-elementen bestaan niet in de hiërarchie. Dit is een van de meest voorkomende fouten van beginnende Android-ontwikkelaars.
onCreate in Fragment verschilt van Activity: hier wordt setContentView niet aangeroepen, maar wordt alleen initialisatie van niet-UI-gerelateerde gegevens uitgevoerd. Fragment splitst het aanmaken van de component en het aanmaken van View op in twee afzonderlijke methoden: onCreate (eenmalig aangeroepen) en onCreateView (elke keer aangeroepen bij het aanmaken of herbouwen van View).
class UserListFragment : Fragment() {
private lateinit var viewModel: UserViewModel
private var binding: FragmentUserListBinding? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ViewModel-initialisatie — overleeft herbouw van View
viewModel = ViewModelProvider(this)[UserViewModel::class.java]
// Argumenten uit FragmentManager
arguments?.let {
viewModel.loadUser(it.getString("user_id") ?: "")
}
// Bewaren bij rotatie
retainInstance = true
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentUserListBinding.inflate(inflater, container, false)
return binding!!.root
}
}
Het belangrijkste verschil tussen onCreate van Activity en Fragment: onCreate in Fragment mag geen View-gerelateerde code bevatten, omdat View kan worden vernietigd en opnieuw aangemaakt (bijvoorbeeld bij het wisselen van ViewPager-tabbladen), terwijl onCreate slechts eenmalig wordt aangeroepen. Het laden van gegevens, configureren van ViewModel en initialiseren van adapters — taken van onCreate, terwijl het koppelen van View — de taak van onViewCreated is.
De parameter savedInstanceState in onCreate — is het mechanisme voor het opslaan en herstellen van de tijdelijke toestand van Activity of Fragment. Wanneer het systeem Activity vernietigt (schermrotatie, geheugengebrek), roept het onSaveInstanceState() aan, waarin de ontwikkelaar een sleutel-waardepaar in Bundle plaatst. Bij het aanmaken van een nieuwe instantie wordt deze Bundle teruggegeven in onCreate.
Bundle ondersteunt de volgende gegevenstypen: String, Integer, Boolean, Long, Float, Double, hun arrays, evenals Parcelable- en Serializable-objecten. Voor complexe objecten wordt Parcelable gebruikt — dit is een efficiënter serialisatiemechanisme, specifiek voor Android. De grootte van Bundle is beperkt tot ongeveer 500 KB — overschrijding van de limiet veroorzaakt een 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)
}
Het is belangrijk om te begrijpen: onSaveInstanceState wordt niet aangeroepen wanneer de gebruiker Activity expliciet sluit via finish() of door op de knop „Terug" te drukken. Het systeem beschouwt dat de gebruiker in dit geval bewust het werk beëindigt en het opslaan van de toestand niet nodig is. Daarom kunt u niet uitsluitend op savedInstanceState vertrouwen voor langdurige gegevensopslag — gebruik Room, DataStore of SharedPreferences.
onCreate wordt uitgevoerd in de hoofdthread (UI) en het systeem wacht op de voltooiing ervan voordat het Activity op het scherm weergeeft. Als onCreate langer dan 5 seconden duurt, toont het systeem een ANR-dialoogvenster (Application Not Responding) en stelt de gebruiker voor de app te sluiten. Langdurige bewerkingen zoals het laden van gegevens uit het netwerk of lezen uit de database moeten naar de achtergrondthread worden verplaatst.
Volgens de aanbevelingen van Google Android Performance (2025) moet onCreate in minder dan 1 seconde worden voltooid op middensegmentapparaten. Gebruik hiervoor: lazy-initialisatie (lazy delegate in Kotlin), stel het laden van zware gegevens uit naar onResume of via coroutines, pas ViewStub toe voor zelden gebruikte UI-componenten, profileer de opstarttijd via Android Vitals.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Lazy-initialisatie — object wordt alleen bij eerste toegang gemaakt
val heavyData by lazy {
HeavyDataLoader.load()
}
// Gegevens laden op de achtergrondthread via lifecycleScope
lifecycleScope.launch(Dispatchers.IO) {
val users = userDao.getAllUsers()
withContext(Dispatchers.Main) {
adapter.submitList(users)
}
}
}
Profileringshulpmiddelen: Android Studio Profiler (tabblad CPU) toont de exacte uitvoeringstijd van elke methode. In Android Vitals (Google Play-console) kunt u de metriek „Koude starttijd" volgen — als de onCreate van uw Activity 500 ms overschrijdt, markeert de console dit als een prestatieprobleem. Wij bij IT Sectr gebruiken Macrobenchmark-tests voor automatische controle van de starttijd van elke Activity in de CI-pijplijn.
ViewModel — de beste manier om gegevens in onCreate te initialiseren die een schermrotatie moeten overleven. ViewModel wordt in onCreate aangemaakt via ViewModelProvider en automatisch bewaard bij configuratiewijziging. Wanneer Activity na rotatie opnieuw wordt aangemaakt, blijft ViewModel in het geheugen en ontvangt onCreate dezelfde ViewModel zonder gegevensverlies.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_profile)
// ViewModel wordt eenmalig gemaakt en overleeft configuratiewijzigingen
val viewModel: ProfileViewModel =
ViewModelProvider(this)[ProfileViewModel::class.java]
// LiveData-observatie — UI werkt automatisch bij bij gegevenswijziging
viewModel.user.observe(this) { user ->
binding?.userName?.text = user.name
binding?.userEmail?.text = user.email
}
// Gegevens laden als ViewModel net is aangemaakt
if (savedInstanceState == null) {
viewModel.loadProfile(userId)
}
}
De combinatie ViewModel + LiveData/StateFlow lost het probleem van schermrotatie op zonder handmatig opslaan in Bundle. ViewModel bewaart gegevens in het geheugen, LiveData abonneert Activity automatisch opnieuw bij herbouw, en StateFlow (uit Kotlin Coroutines) voegt reactiviteit toe met ondersteuning voor coroutines. Dit is de standaardarchitectuur die door Google wordt aanbevolen in de gids Guide to App Architecture.
Zelfs ervaren ontwikkelaars maken typische fouten in onCreate. Laten we vijf veelvoorkomende problemen bekijken en hoe u ze kunt vermijden.
De meest voorkomende fout — proberen een View te vinden via findViewById vóór de aanroep van setContentView. Alle View-elementen worden gemaakt op het moment van het inflaten van de layout, dus elke verwijzing naar findViewById vóór setContentView retourneert null en veroorzaakt een NullPointerException bij het proberen te gebruiken van View. Oplossing: strikte volgorde — eerst super, dan setContentView, daarna findViewById of ViewBinding.
Het laden van gegevens uit het netwerk, lezen uit de database of het verwerken van grote arrays direct in onCreate blokkeert het renderen van het eerste frame. De gebruiker ziet een zwart scherm totdat onCreate is voltooid, wat de perceptie van de snelheid van de app verslechtert. Oplossing: gebruik lifecycleScope.launch voor asynchrone bewerkingen, toon een skelet (placeholder UI) tot het laden is voltooid.
Als bij schermrotatie de toestand niet uit Bundle wordt hersteld, verliest de gebruiker alle niet-opgeslagen invoer: tekst in formuliervelden, scrollpositie, geselecteerde elementen. Oplossing: controleer altijd savedInstanceState != null in onCreate voor het herstellen van gegevens, zelfs als het verlies van toestand onwaarschijnlijk lijkt.
Anonieme klassen en lambda's in onCreate kunnen impliciet een verwijzing naar Activity vasthouden na de vernietiging ervan. Bijvoorbeeld een Handler die in onCreate is aangemaakt, blijft uitgestelde taken uitvoeren, zelfs nadat Activity is vernietigd. Oplossing: gebruik LifecycleObserver, ViewModel en lifecycleScope, die taken automatisch annuleren bij vernietiging.
Initialisatie van View in onCreate van Fragment — een logische fout, omdat View opnieuw kan worden aangemaakt zonder aanroep van onCreate. Als een luisteraar in onCreate wordt ingesteld en View wordt gekoppeld in onCreateView, blijft de luisteraar bij herbouw aan de oude View hangen. Oplossing: al het View-werk uitvoeren in onViewCreated, en onCreate alleen laten voor initialisatie van de datalaag.
Veelgestelde vragen
Ja, het overschrijven van onCreate is verplicht voor elke Activity die een gebruikersinterface weergeeft. Zonder dit kan setContentView niet worden aangeroepen en de XML-layout niet worden geladen. Als Activity geen UI heeft (bijvoorbeeld een transparante Activity-stub), wordt onCreate nog steeds overschreven, maar zonder aanroep van setContentView.
Nee, onCreate kan niet opnieuw worden aangeroepen voor dezelfde Activity-instantie. Als Activity wordt vernietigd en opnieuw aangemaakt (schermrotatie, geheugengebrek), is dit een nieuwe instantie met een nieuwe onCreate-aanroep. Uitzondering — de methode recreate(), die geforceerd Activity vernietigt en opnieuw aanmaakt, maar dit is ook het opnieuw aanmaken van een nieuwe instantie.
Als super.onCreate(savedInstanceState) niet wordt aangeroepen, gooit Android Runtime een SuperNotCalledException en crasht de app. Het systeem vereist strikt dat elke overschreven levenscyclusmethode zijn super-versie aanroept — dit garandeert de correcte werking van de interne toestandsautomaat.
Het belangrijkste verschil: onCreate in Activity laadt UI via setContentView, terwijl onCreate in Fragment alleen gegevens initialiseert. Fragment maakt View aan in de afzonderlijke methode onCreateView, die meerdere keren kan worden aangeroepen (bijvoorbeeld bij het wisselen van tabbladen), terwijl onCreate van Fragment eenmalig wordt aangeroepen gedurende de levensduur van de Fragment-instantie.
Gegevens die in onCreate zijn geïnitialiseerd, worden opgeslagen in de velden van de klasse Activity of Fragment. Bijvoorbeeld private lateinit var binding: ActivityMainBinding wordt op klasseniveau gedeclareerd, geïnitialiseerd in onCreate en is toegankelijk in alle volgende methoden. Voor gegevens die schermrotatie overleven, gebruikt u ViewModel met LiveData of StateFlow.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook