onStart — is de levenscyclusmethode van Android die wordt aangeroepen wanneer Activity of Fragment zichtbaar worden voor de gebruiker. Op dat moment verschijnt het scherm op de display van het apparaat, maar kan nog niet interactief zijn — de invoerfocus ontbreekt tot de aanroep van onResume. De onStart-methode is ideaal voor het registreren van systeemlisteners, verbinding maken met geolocatiediensten en het starten van animaties die moeten werken zolang de component zichtbaar is op het scherm. Lees meer over de volledige levenscyclus van Activity in het artikel Activity Lifecycle.
Belangrijkste
onStart — de tweede methode van de Activity-levenscyclus, aangeroepen door het systeem na onCreate (of na onRestart bij terugkeer uit gestopte toestand). Op het moment van aanroep worden Activity of Fragment zichtbaar op het scherm. De gebruiker ziet de interface, maar het scherm is nog niet klaar voor interactie — de invoerfocus verschijnt pas na onResume.
De onStart-methode maakt deel uit van de “zichtbare levensduur” (visible lifetime) van Activity — het interval tussen onStart en onStop. Gedurende deze periode kan Activity gedeeltelijk worden bedekt door andere vensters (bijvoorbeeld een transparante Activity of dialoogvenster), maar de UI blijft zichtbaar. Dit onderscheidt de zichtbare levensduur van de “levensduur op de voorgrond” (onResume — onPause), wanneer Activity volledige invoerfocus heeft.
Het begrijpen van deze drielaagse hiërarchie is van cruciaal belang voor de juiste verdeling van code. onCreate — eenmalige initialisatie, onStart — verbinden van zichtbare bronnen, onResume — monopolietoegang tot exclusieve bronnen. Een ontwikkelaar die deze niveaus verwart, riskeert geheugenlekken of incorrect gedrag van de app bij het schakelen tussen schermen.
In Activity wordt de onStart-methode elke keer aangeroepen wanneer het scherm op de display verschijnt — zowel bij de eerste start (na onCreate) als bij terugkeer uit de achtergrondmodus (na onRestart). In tegenstelling tot onCreate kan onStart meerdere keren worden aangeroepen tijdens de levensduur van een Activity-instantie, dus hier wordt code geplaatst die elke keer moet worden uitgevoerd wanneer het scherm verschijnt.
class DashboardActivity : AppCompatActivity() {
private val connectivityReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val isConnected = ... // ConnectivityManager controle
binding?.statusIndicator?.setColor(
if (isConnected) Color.GREEN else Color.RED
)
}
}
override fun onStart() {
super.onStart()
registerReceiver(
connectivityReceiver,
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
)
SensorManager.getInstance().registerStepCounter()
}
override fun onStop() {
unregisterReceiver(connectivityReceiver)
SensorManager.getInstance().unregisterStepCounter()
super.onStop()
}
}
Belangrijke regel: alle bronnen die in onStart zijn verbonden, moeten in onStop worden vrijgemaakt. Dit garandeert dat wanneer Activity van het scherm is verborgen, deze geen batterij verbruikt, geen systeemgebeurtenissen beluistert en geen geheugen in beslag neemt. Android Studio bevat lint-regels die waarschuwen voor registratie van BroadcastReceiver zonder bijbehorende afmelding.
onStart in Fragment is nauw verbonden met de levenscyclus van de Activity-container. Fragment ontvangt de onStart-aanroep nadat de Activity waarin het zich bevindt onStart heeft ontvangen. Echter, als Fragment in uitgestelde modus is toegevoegd (FragmentTransaction.commit() zonder addToBackStack), kan onStart met vertraging worden aangeroepen.
class MapFragment : Fragment() {
private var mapView: MapView? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
mapView = MapView(requireContext())
return mapView!!
}
override fun onStart() {
super.onStart()
mapView?.onStart()
LocationService.connect(requireContext())
}
override fun onStop() {
mapView?.onStop()
LocationService.disconnect()
super.onStop()
}
}
Specificiteit van Fragment.onStart: als Fragment zich in een ViewPager met offscreenPageLimit = 1 bevindt, krijgen aangrenzende fragmenten ook onStart voordat ze zichtbaar worden. Dit kan leiden tot vroegtijdige registratie van listeners. Gebruik in zulke gevallen de methode setUserVisibleHint() of controleer isVisible binnen onStart om listeners alleen voor werkelijk zichtbare fragmenten te registreren.
Het belangrijkste verschil tussen onStart en onResume — het niveau van schermactiviteit. onStart geeft aan dat Activity zichtbaar is op het scherm, maar niet noodzakelijk op de voorgrond staat. onResume geeft aan dat Activity op de voorgrond staat en invoerfocus heeft. Het verschil wordt gedemonstreerd met een dialoogvenster: wanneer een Dialog boven Activity verschijnt, verliest Activity onResume (onPause wordt aangeroepen), maar blijft zichtbaar — onStart/onStop worden niet aangeroepen.
De verschiltabel laat duidelijk zien in welke scenario’s elke methode wordt aangeroepen:
| Scenario | onStart | onResume |
|---|---|---|
| Starten van de app | Aangeroepen | Aangeroepen |
| Boven Activity is Dialog geopend | Niet aangeroepen | onPause (focusverlies) |
| Indrukken van “Home”-knop | onStop (verborgen) | onPause → onStop |
| Terugkeren uit “Recente apps” | onStart (zichtbaar) | onResume (focus) |
| Schermrotatie | onCreate → onStart | → onResume |
| Binnenkomend gesprek | onStop (verborgen) | onPause → onStop |
Deze tabel helpt de ontwikkelaar te beslissen in welke methode specifieke code moet worden geplaatst. Als de app bijvoorbeeld het afspelen van video moet onderbreken bij elke bedekking van het scherm (zelfs met een dialoog), wordt de code in onPause geplaatst. Als de video alleen moet stoppen bij volledige verberging van het scherm — wordt de code in onStop geplaatst.
onStart — de optimale plaats voor het registreren van listeners die alleen moeten werken zolang Activity zichtbaar is op het scherm. Dit betreft drie hoofdtypen systeemcomponenten: BroadcastReceiver voor systeemgebeurtenissen, LocationListener voor geolocatie en SensorListener voor apparaatsensoren.
BroadcastReceiver wordt dynamisch geregistreerd via Context.registerReceiver() in onStart en afgemeld in onStop via unregisterReceiver(). Dynamische registratie heeft de voorkeur boven statische (in het manifest), omdat het de levensduur van de ontvanger beperkt tot de zichtbaarheidsperiode van Activity — de app wordt niet geactiveerd door systeem broadcast-berichten wanneer Activity verborgen is.
private val batteryReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
binding?.batteryText?.text = "$level%"
}
}
override fun onStart() {
super.onStart()
registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}
override fun onStop() {
unregisterReceiver(batteryReceiver)
super.onStop()
}
Geolocatie en sensoren — resource-intensieve operaties. Het aanvragen van GPS-updates in onStart en annuleren in onStop garandeert dat de app geen batterij verbruikt wanneer het scherm verborgen is. Voor nauwkeurige afstelling wordt requestLocationUpdates gebruikt met een minimum interval en afstand — bijvoorbeeld 10 seconden en 10 meter, wat een optimale balans geeft tussen nauwkeurigheid en energieverbruik.
Het starten van animaties in onStart, niet in onCreate, garandeert dat de animatie elke keer start wanneer het scherm verschijnt. Als u de animatie in onCreate start, werkt deze alleen bij de eerste creatie van Activity, maar niet bij terugkeer uit de achtergrondmodus. onStart wordt elke keer aangeroepen wanneer Activity zichtbaar wordt, wat het de ideale plaats maakt voor het starten van cyclische animaties en overgangen.
private lateinit var pulseAnimator: ValueAnimator
override fun onStart() {
super.onStart()
pulseAnimator.start()
binding?.loadingIndicator?.animate()?.alpha(1f)?.start()
}
override fun onStop() {
pulseAnimator.cancel()
binding?.loadingIndicator?.animate()?.cancel()
super.onStop()
}
Voor animaties die ObjectAnimator of ValueAnimator gebruiken, is het belangrijk om cancel() in onStop aan te roepen. Als de animatie blijft werken na het verbergen van Activity, verbruikt deze onnodig GPU- en CPU-bronnen, wat de prestaties van het apparaat vermindert en de batterij sneller leegmaakt. Android Studio Profiler (GPU-grafiek) maakt het mogelijk actieve animaties te volgen en lekken op te sporen.
De koppelregel onStart/onStop is ook van toepassing op het werken met de camera voor preview (CameraX). Het openen van de camera in onStart en sluiten in onStop garandeert dat de camera niet is geblokkeerd voor andere apps wanneer uw app niet zichtbaar is op het scherm. Schending van deze regel is een van de vaak voorkomende oorzaken van negatieve beoordelingen in Google Play.
Veelgestelde vragen
onStart — voor listeners die moeten werken zolang het scherm zichtbaar is (BroadcastReceiver, LocationListener, SensorListener). onResume — voor bronnen die monopolietoegang vereisen (camera, video-opname, spraakherkenning). Listeners voor systeemgebeurtenissen hebben geen monopolietoegang nodig en kunnen werken bij gedeeltelijke bedekking — ze worden geregistreerd in onStart. De camera mag alleen actief zijn bij volledige focus — wordt geopend in onResume.
onStart wordt altijd aangeroepen als Activity overgaat naar de zichtbare toestand. Het enige scenario zonder onStart — Activity wordt gemaakt en onmiddellijk beëindigd (bijvoorbeeld vanwege een fout in onCreate). In dit geval wordt na onCreate direct onDestroy aangeroepen. Maar dit is een noodgeval dat niet mag voorkomen in correct geschreven code.
Ja, onStart kan onResume niet krijgen als er direct een andere Activity of transparant venster boven Activity wordt geopend. Als bijvoorbeeld na onCreate een authenticatiescherm wordt gestart (Activity A → Activity B), wordt in Activity A onStart aangeroepen, maar onResume niet — het krijgt direct onPause → onStop bij bedekking door scherm B.
onStart kan meerdere keren worden aangeroepen tijdens de levensduur van een Activity-instantie. Elke keer dat Activity van verborgen toestand (onStop) naar zichtbare toestand overgaat, wordt onStart aangeroepen. In de praktijk kan onStart bij actief gebruik van de app tientallen of honderden keren per sessie worden aangeroepen.
Gegevens laden in onStart is gerechtvaardigd als de gegevens elke keer moeten worden bijgewerkt wanneer het scherm verschijnt. Bijvoorbeeld een nieuwsfeed of meldingenlijst. Maar het laden moet asynchroon zijn — via coroutines met lifecycleScope, om de UI-thread niet te blokkeren. Voor gegevens die niet veranderen tussen schermverschijningen, volstaat het om ze eenmalig in onCreate te laden.
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