onStart: podstata, viditelnost Activity na obrazovce Androidu

Autor: IT Sectr Publikováno: 2026-03-04 Doba čtení: 9 min

onStart — je metoda životního cyklu Androidu, která je volána, když se Activity nebo Fragment stanou viditelnými pro uživatele. V tomto okamžiku se obrazovka objeví na displeji zařízení, ale ještě nemůže interagovat s uživatelem — vstupní fokus chybí do zavolání onResume. Metoda onStart je ideální pro registraci systémových posluchačů, připojení ke službám geolokace a spouštění animací, které by měly fungovat, dokud je komponent viditelný na obrazovce. Více o úplném životním cyklu Activity si přečtěte v článku Activity Lifecycle.

Hlavní

  • onStart — volá se, když se Activity nebo Fragment stane viditelným na obrazovce; předchází onResume
  • Registrace posluchačů — BroadcastReceiver, LocationListener, SensorListener se registrují v onStart a odhlašují se v onStop
  • Animace — spouštění animací, které by měly fungovat, dokud je obrazovka viditelná; pozastavení v onStop
  • Bound-služby — připojení ke klientským-serverovým službám přes bindService v onStart, odpojení v onStop
  • onStart vs onResume — onStart = viditelnost, onResume = fokus + interakce; různé úrovně aktivity obrazovky
  • Fragment.onStart — volá se po Activity.onStart, když se Fragment stane viditelným v kontejneru
  • Pár onStart/onStop — zdroje připojené v onStart se musí uvolnit v onStop, aby se zabránilo únikům

Podstata metody onStart v Androidu

onStart — druhá metoda životního cyklu Activity, která je volána systémem po onCreate (nebo po onRestart při návratu ze zastaveného stavu). V okamžiku volání onStart se Activity nebo Fragment stanou viditelnými na obrazovce. Uživatel vidí rozhraní, ale obrazovka ještě není připravena k interakci — vstupní fokus se objeví až po onResume.

Metoda onStart patří do „viditelné životnosti" (visible lifetime) Activity — intervalu mezi onStart a onStop. Během tohoto období může být Activity částečně zakryta jinými okny (například průhlednou Activity nebo dialogovým oknem), ale její UI zůstává viditelné. To odlišuje viditelnou životnost od „životnosti na popředí" (onResume — onPause), kdy má Activity plný vstupní fokus.

Porozumění této tříúrovňové hierarchii je kriticky důležité pro správné rozložení kódu. onCreate — jednorázová inicializace, onStart — připojení viditelných zdrojů, onResume — monopolní přístup k exkluzivním zdrojům. Vývojář, který tyto úrovně zaměňuje, riskuje vytvoření úniků paměti nebo nesprávné chování aplikace při přepínání mezi obrazovkami.

onStart v Activity

V Activity je metoda onStart volána pokaždé, když se obrazovka objeví na displeji — jak při prvním spuštění (po onCreate), tak při návratu z režimu pozadí (po onRestart). Na rozdíl od onCreate, onStart může být volán vícekrát během životnosti instance Activity, proto se sem umísťuje kód, který by se měl provést pokaždé, když se obrazovka objeví.

kotlin
class DashboardActivity : AppCompatActivity() {
    private val connectivityReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val isConnected = ... // kontrola ConnectivityManager
            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()
    }
}

Klíčové pravidlo: všechny zdroje připojené v onStart musí být uvolněny v onStop. To zaručuje, že když je Activity skryta z obrazovky, nespotřebovává baterii, nenaslouchá systémovým událostem a nezabírá paměť. Android Studio obsahuje pravidla lint, která varují před registrací BroadcastReceiver bez odpovídajícího odhlášení.

onStart ve Fragmentu

onStart ve Fragmentu je úzce spjat s životním cyklem kontejnerového Activity. Fragment obdrží volání onStart poté, co Activity, ve kterém se nachází, obdrželo onStart. Pokud byl však Fragment přidán v odloženém režimu (FragmentTransaction.commit() bez addToBackStack), onStart může být volán se zpožděním.

kotlin
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()
    }
}

Specifičnost Fragment.onStart: pokud se Fragment nachází ve ViewPager s offscreenPageLimit = 1, sousední fragmenty také obdrží onStart dříve, než se stanou viditelnými. To může vést k předčasné registraci posluchačů. V takových případech použijte metodu setUserVisibleHint() nebo kontrolu isVisible uvnitř onStart pro registraci posluchačů pouze pro skutečně viditelné fragmenty.

Rozdíl mezi onStart a onResume

Hlavní rozdíl mezi onStart a onResume — úroveň aktivity obrazovky. onStart signalizuje, že Activity je viditelné na obrazovce, ale nemusí být na popředí. onResume signalizuje, že Activity je na popředí a má vstupní fokus. Rozdíl je demonstrován na příkladu dialogového okna: když se nad Activity objeví Dialog, Activity ztrácí onResume (volá se onPause), ale zůstává viditelné — onStart/onStop se nevolají.

Tabulka rozdílů jasně ukazuje, ve kterých scénářích je každá metoda volána:

ScénářonStartonResume
Spuštění aplikaceVolánoVoláno
Nad Activity je otevřen DialogNení volánoonPause (ztráta fokusu)
Stisknutí tlačítka „Domů"onStop (skryto)onPause → onStop
Návrat z „Naposledy"onStart (viditelné)onResume (fokus)
Otočení obrazovkyonCreate → onStart→ onResume
Příchozí hovoronStop (skryto)onPause → onStop

Tato tabulka pomáhá vývojáři rozhodnout, do které metody umístit konkrétní kód. Pokud například aplikace musí pozastavit přehrávání videa při jakémkoli zakrytí obrazovky (i dialogem), kód se umístí do onPause. Pokud se má video zastavit pouze při úplném skrytí obrazovky — kód se umístí do onStop.

Registrace posluchačů a služeb

onStart — optimální místo pro registraci posluchačů, kteří by měli fungovat pouze dokud je Activity viditelné na obrazovce. Týká se to tří hlavních typů systémových komponent: BroadcastReceiver pro systémové události, LocationListener pro geolokaci a SensorListener pro senzory zařízení.

BroadcastReceiver v onStart

BroadcastReceiver se registruje dynamicky přes Context.registerReceiver() v onStart a odhlašuje se v onStop přes unregisterReceiver(). Dynamická registrace je výhodnější než statická (v manifestu), protože omezuje životnost přijímače na období viditelnosti Activity — aplikace se neprobouzí kvůli systémovým broadcast zprávám, když je Activity skryté.

kotlin
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()
}

LocationListener a SensorListener

Geolokace a senzory — operace náročné na zdroje. Žádost o GPS aktualizace v onStart a zrušení v onStop zaručuje, že aplikace nespotřebovává baterii, když je obrazovka skryta. Pro přesné nastavení se používá requestLocationUpdates s minimálním intervalem a vzdáleností — například 10 sekund a 10 metrů, což poskytuje optimální rovnováhu mezi přesností a spotřebou energie.

Animace a onStart

Spouštění animací v onStart, ne v onCreate, zaručuje, že animace startuje pokaždé, když se obrazovka objeví. Pokud spustíte animaci v onCreate, bude fungovat pouze při prvním vytvoření Activity, ale ne při návratu z režimu pozadí. onStart je volán pokaždé, když se Activity stane viditelným, což z něj dělá ideální místo pro spouštění cyklických animací a přechodů.

kotlin
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()
}

Pro animace používající ObjectAnimator nebo ValueAnimator je důležité volat cancel() v onStop. Pokud animace pokračuje v činnosti po skrytí Activity, zbytečně spotřebovává zdroje GPU a CPU, což snižuje výkon zařízení a zrychluje vybíjení baterie. Android Studio Profiler (graf GPU) umožňuje sledovat aktivní animace a odhalovat úniky.

Pravidlo páru onStart/onStop platí také pro práci s kamerou pro náhled (CameraX). Otevření kamery v onStart a zavření v onStop zaručuje, že kamera není blokována pro jiné aplikace, když vaše aplikace není viditelná na obrazovce. Porušení tohoto pravidla je jedním z častých důvodů negativních recenzí v Google Play.

Často kladené otázky

Jaký je rozdíl mezi onStart a onResume pro registraci posluchačů?

onStart — pro posluchače, kteří by měli fungovat, dokud je obrazovka viditelná (BroadcastReceiver, LocationListener, SensorListener). onResume — pro zdroje vyžadující monopolní přístup (kamera, videozáznam, rozpoznávání řeči). Posluchači systémových událostí nevyžadují monopolní přístup a mohou fungovat při částečném zakrytí — registrují se v onStart. Kamera by měla být aktivní pouze při plném fokusu — otevírá se v onResume.

Proč se onStart nemusí volat?

onStart je vždy voláno, pokud Activity přejde do viditelného stavu. Jediný scénář bez onStart — Activity je vytvořeno a okamžitě ukončeno (například kvůli chybě v onCreate). V tomto případě po onCreate bezprostředně následuje onDestroy. Toto je však nouzový scénář, který by se neměl vyskytovat ve správně napsaném kódu.

Může být onStart voláno bez onResume?

Ano, onStart nemusí obdržet onResume, pokud se nad Activity okamžitě otevře jiné Activity nebo průhledné okno. Například, pokud se po onCreate spustí obrazovka autentizace (Activity A → Activity B), v Activity A je onStart voláno, ale onResume ne — obdrží přímo onPause → onStop při zakrytí obrazovkou B.

Kolikrát může být onStart voláno?

onStart může být voláno vícekrát během životnosti instance Activity. Pokaždé, když Activity přejde ze skrytého stavu (onStop) do viditelného stavu, je voláno onStart. V praxi, při aktivním používání aplikace, může být onStart voláno desítky nebo stovkykrát za relaci.

Vyplatí se načítat data v onStart?

Načítání dat v onStart je odůvodněné, pokud by se data měla aktualizovat pokaždé, když se obrazovka objeví. Například zpravodajský kanál nebo seznam oznámení. Načítání by však mělo být asynchronní — přes korutiny s lifecycleScope, aby neblokovalo UI vlákno. Pro data, která se nemění mezi zobrazeními obrazovky, stačí je načíst jednou v onCreate.

Shrnutí

  • onStart — metoda viditelné životnosti; volá se, když se Activity nebo Fragment objeví na obrazovce
  • Registrace v onStart — BroadcastReceiver, LocationListener, SensorListener se registrují v onStart a odhlašují v onStop
  • onStart vs onResume — onStart = viditelnost, onResume = vstupní fokus; různé úrovně pro různé typy zdrojů
  • Animace — spouštění cyklických animací v onStart, zastavení v onStop; zabraňuje únikům zdrojů GPU
  • Fragment.onStart — vázán na Activity.onStart; ve ViewPager je volán pro sousední fragmenty předem
  • Pravidlo párů — všechny zdroje onStart musí být uvolněny v onStop, jinak únik paměti a baterie
  • Načítání dat — v onStart se načítají data, která by se měla aktualizovat při každém zobrazení obrazovky

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í.

Prodiskutovat projekt

Přečtěte si také