onDestroy: mi ez, az Activity befejezése Androidban

Szerző: IT Sectr Megjelenés: 2026-03-04 Olvasási idő: 8 perc

onDestroy — az Activity és Fragment életciklusának végső metódusa Androidban, amely a komponens teljes megsemmisítése előtt hívódik meg. Az onDestroy jelzi, hogy az Activity vagy Fragment befejezi a munkáját: minden erőforrást fel kell szabadítani, a beágyazott fragmenseket — meg kell semmisíteni, a ViewModel-t — ki kell tisztítani. A Google adatai szerint az onDestroy az Activity befejezésének 100%-ában meghívódik, de a folyamat megszakításakor (process death) a rendszer teljesen kihagyhatja az onDestroy meghívását. Az Android onDestroy dokumentációja hangsúlyozza, hogy ez a metódus nem garantálja a meghívást vészhelyzet esetén.

Főbb pontok

  • onDestroy — az utolsó hívás az Activity vagy Fragment megsemmisítése előtt, az erőforrások végső tisztítására szolgál.
  • Az onDestroy meghívása nem garantált a rendszer általi folyamatmegszakításkor (process death) — ne támaszkodjon rá kritikus adatok mentéséhez.
  • Az onDestroy-ben le kell állítani a háttérfeladatokat, be kell zárni a socketeket és adatbázisokat, ki kell tisztítani a ViewModelStore-t.
  • Különbség az onStop-tól: onStop — láthatóság elvesztése (Activity él a memóriában), onDestroy — teljes megsemmisítés.
  • Az isFinishing() az onDestroy-ben mutatja, hogy az Activity a felhasználó parancsára (finish()) vagy a rendszer döntése alapján fejeződik be.

onDestroy: mi ez Androidban?

onDestroy — egy visszahívási metódus, amelyet az Android hív meg, mielőtt véglegesen megsemmisíti az Activity-t vagy Fragment-et. Ez az utolsó lehetőség a fejlesztő számára, hogy felszabadítsa az erőforrásokat, leállítsa a háttérműveleteket és befejezze az adatokkal való munkát. Az onDestroy végrehajtása után az Activity/Fragment példány megjelölésre kerül a szemétgyűjtő (GC) számára, és többé nem használható.

Az onDestroy meghívásának okai:

  • Explicit finish() hívás — a felhasználó megnyomta a „Vissza" gombot vagy a fejlesztő meghívta a finishActivity()-t.
  • Képernyő elforgatása — az Activity megsemmisül és újra létrejön új konfigurációval.
  • Konfiguráció változása — billentyűzet, nyelvváltás, képernyőméret változása (multi-window).
  • Rendszer döntése — az Android megszakítja az Activity-t az erőforrások felszabadításához (de az onDestroy lehet, hogy nem hívódik meg).

A Google Android Vitals (2025) statisztikái szerint az Activity megsemmisítések körülbelül 12%-a képernyőelforgatásból, 65%-a finish()-ből és 23%-a konfigurációváltozásból ered. A folyamatmegszakítások aránya az onDestroy kihagyásával körülbelül 5–8% a kis RAM-mal (4 GB alatt) rendelkező eszközöktől függően.

Mikor hívódik meg az onDestroy — és mikor nem

Az onDestroy a legtöbb szabványos forgatókönyvben meghívódik, de vannak fontos kivételek, amelyeket a fejlesztőnek figyelembe kell vennie. Az onDestroy meghívási garanciáinak megértése kritikus fontosságú az alkalmazás architektúrája szempontjából, különösen az adatok mentése és a WorkManager-feladatok leállítása terén.

Mikor hívódik meg az onDestroy:

  • A felhasználó megnyomja a „Vissza" gombot — Activity.finish() → onPause → onStop → onDestroy.
  • Képernyő elforgatása — az Activity megsemmisül (onPause → onStop → onDestroy), majd újra létrejön.
  • Konfiguráció változása — rendszerbeállítás, amely az Activity újralétrehozását igényli.
  • finishAffinity() hívása — az összes Activity befejezése a veremben.
  • Fragment eltávolítása a FragmentManager-ből — a Fragment onPause → onStop → onDestroyView → onDestroy → onDetach hívást kap.

Mikor NEM hívódik meg az onDestroy:

  • Folyamat megszakítása a rendszer által (process death) — az Android megöli a teljes alkalmazásfolyamatot memóriahiány esetén. Az Activity nem kap onDestroy-t, mert a folyamat a Linux kernel szintjén fejeződik be.
  • Vészhelyzeti befejezés — egy el nem kapott kivétel a fő szálban megöli az alkalmazást az onDestroy meghívása nélkül.
  • Force Stop — a felhasználó kényszerítetten leállítja az alkalmazást a beállításokban.

Az onDestroy meghívási garanciájának hiánya miatt a Google azt javasolja: soha ne támaszkodjon az onDestroy-ra kritikus adatok mentéséhez. Használja az onSaveInstanceState()-t, WorkManager-t vagy Room-ot automatikus mentéssel. Az onDestroy — az erőforrások felszabadítására szolgál, nem az adatok perzisztenciájára.

onDestroy az Activity-ben és Fragment-ben: közös és eltérő vonások

Az onDestroy mind az Activity, mind a Fragment számára létezik, de különböző szerződésekkel. A Fragment életciklusa részletesebb: az onDestroy mellett létezik onDestroyView (a View hierarchia megsemmisítése) és onDetach (leválasztás az Activity-ről).

KomponensMegsemmisítési metódusokSorrendViewModel túléli
ActivityonDestroyonPause → onStop → onDestroyNem (csak ha a ViewModelStore nincs elmentve)
FragmentonDestroyView, onDestroy, onDetachonPause → onStop → onDestroyView → onDestroy → onDetachIgen, ha a Fragment nincs eltávolítva

A legfontosabb különbség: a Fragment esetében a View gyakrabban jön létre újra, mint maga a Fragment. Képernyőelforgatáskor a Fragment átesik az onDestroyView-n (View megsemmisítése), de maga a Fragment és annak ViewModel-je életben marad. Az onDestroyView — a megfelelő hely a View-ra mutató referenciák tisztítására a memóriaszivárgás elkerülése érdekében. A Fragment onDestroy-je — az Activity onDestroy-jének analógiája, a Fragment teljes eltávolításakor hívódik meg.

A beágyazott fragmentek (child fragments) a szülő Fragment onDestroy-je előtt semmisülnek meg. Az Activity-ben a gyermek fragmentek az onDestroy hívásakor kapnak onDestroy-t a szülő Activity-től. A sorrend garantált: a fragmentek korábban fejeződnek be, mint az őket tartalmazó Activity.

Mit tegyünk az onDestroy-ben: tisztítási ellenőrzőlista

Az onDestroy az összes olyan erőforrás felszabadítására szolgál, amelyek nem élhetnek tovább az Activity-nél vagy Fragment-nél. Ellentétben az onStop-pal, amely az erőforrásokat a visszatérésig szabadítja fel, az onDestroy végleges tisztítást végez.

Kötelező műveletek ellenőrzőlistája az onDestroy-ben:

  • Coroutine-ok és Flow leállítása — állítsa le azokat a job-okat, amelyek nem kapcsolódnak a viewModelScope-hoz. A viewModelScope automatikusan leáll, de a lifecycleScope az Activity életciklusához kapcsolódik.
  • Socketek és csatornák bezárása — WebSocket (OkHttp), BluetoothSocket, ServerSocket. Nyitva tartásuk a megsemmisítés után rendszererőforrás-szivárgást okoz.
  • Fájlok és adatfolyamok bezárása — FileInputStream, FileOutputStream, Cursor. A Cursor ANR-t okozhat a ContentProvider-en, ha nincs bezárva.
  • Leiratkozás ContentObserver-ről — ha az Activity tartalomváltozásokat (kapcsolatok, médiatár) figyel.
  • Leiratkozás BroadcastReceiver-ről — a dinamikusan regisztrált receiver-eket le kell állítani.
  • Adatbázis bezárása — a Room automatikusan bezárja a kapcsolatot az Application megsemmisítésekor, de a közvetlen SQLiteDatabase manuális close()-t igényel.

Mit NE tegyünk az onDestroy-ben: Ne mentsen adatokat az onDestroy-ben — használja az onPause-t vagy onSaveInstanceState-t. Ne indítson új Service-t vagy WorkManager-feladatot — az Activity megsemmisül, és nem tudja nyomon követni az eredményt. Ne próbálja frissíteni a UI-t — a View hierarchia már megsemmisült vagy megsemmisítés alatt áll; a findViewById() hívása null-t ad vissza.

onDestroy és ViewModel: együttműködés

A ViewModel úgy lett tervezve, hogy túlélje az Activity onDestroy-jét képernyőelforgatáskor, de finish()-kor az Activity-vel együtt megsemmisüljön. Ez az aszimmetrikus viselkedés — a fejlesztők körében a zavar fő oka.

Képernyőelforgatáskor:

  • Activity: onPause → onStop → onDestroy (Activity megsemmisült).
  • ViewModel: NEM semmisült meg — a ViewModelStore megőrződik és átadásra kerül az új Activity-nek.
  • Új Activity: onCreate → onStart → onResume, ugyanazt a ViewModel-t kapja.

finish()-kor (a felhasználó megnyomta a „Vissza" gombot):

  • Activity: onPause → onStop → onDestroy.
  • ViewModel: onCleared() — az Activity onDestroy-je után hívódik meg.
  • Minden viewModelScope coroutine automatikusan leáll.

Tehát a viewModelScope leállítása az onDestroy-ben nem szükséges — a ViewModel ezt magától megteszi. Ha a lifecycleScope-ot használja (amely az Activity-hez kapcsolódik, nem a ViewModel-hez), állítsa le az onDestroy-ben a lifecycleScope.cancel() segítségével, vagy kezelje a Job-ot manuálisan.

Kódpéldák onDestroy-vel Kotlinban

1. példa: onDestroy Activity a lifecycleScope coroutine leállításával

Bemutatja a lifecycleScope helyes kezelését Activity-ben: a coroutine elindul a hálózati állapot figyelésére és leáll az onDestroy-ben.

kotlin
class NetworkMonitorActivity : AppCompatActivity() {
    private val networkCallback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            Log.d("NetworkMonitor", "Hálózat elérhető")
        }
        override fun onLost(network: Network) {
            Log.d("NetworkMonitor", "Hálózat elveszett")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_network)
        val connectivityManager = getSystemService(ConnectivityManager::class.java)
        connectivityManager.registerDefaultNetworkCallback(networkCallback)
        lifecycleScope.launch {
            Log.d("NetworkMonitor", "Hálózatfigyelés elindítva")
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        val connectivityManager = getSystemService(ConnectivityManager::class.java)
        connectivityManager.unregisterNetworkCallback(networkCallback)
        Log.d("NetworkMonitor", "onDestroy: callback leállítva")
    }
}

Az onDestroy-ben a hálózati callback regisztrációja leáll. A lifecycleScope automatikusan leáll az életciklus megsemmisülésekor — a coroutine külön leállítása nem szükséges. A hálózati callback-et feltétlenül le kell iratkozni, különben a rendszerben marad az Activity megsemmisítése után is.

2. példa: onDestroy Fragment a View referenciák tisztításával

A Fragment helyesen tisztítja a View referenciákat az onDestroyView-ben, megelőzve a lezárások által okozott memóriaszivárgást.

kotlin
class ProfileFragment : Fragment() {
    private var avatarView: ImageView? = null
    private var progressBar: ProgressBar? = null
    private val imageLoader = ImageLoader()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        avatarView = view.findViewById(R.id.avatar)
        progressBar = view.findViewById(R.id.progress)
        loadProfile()
    }

    private fun loadProfile() {
        viewLifecycleOwner.lifecycleScope.launch {
            try {
                progressBar?.visibility = View.VISIBLE
                val bitmap = imageLoader.load("https://example.com/avatar.png")
                avatarView?.setImageBitmap(bitmap)
            } finally {
                progressBar?.visibility = View.GONE
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        avatarView = null
        progressBar = null
        imageLoader.cancel()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("ProfileFragment", "onDestroy: Fragment teljesen megsemmisült")
    }
}

Az onDestroyView-ben a View referenciák nullára állítódnak — ez megakadályozza a memóriaszivárgást, ha az imageLoader-ben lévő lezárás megtart egy referenciát az avatarView-ra. Maga a Fragment és annak ViewModel-je életben maradnak az onDestroy-ig. Az imageLoader.cancel() leállítja a betöltést, ha a Fragment elhagyja a képernyőt.

3. példa: isFinishing ellenőrzése az onDestroy-ben

Az isFinishing() használata lehetővé teszi annak megkülönböztetését, hogy az Activity a felhasználó parancsára vagy újralétrehozás céljából fejeződik be.

kotlin
class AnalyticsActivity : AppCompatActivity() {
    private val analytics = Analytics()

    override fun onDestroy() {
        if (isFinishing) {
            Log.d("AnalyticsActivity", "Activity finish()-sel fejeződik be — analitikát küldünk")
            analytics.sendSessionEnd()
        } else {
            Log.d("AnalyticsActivity", "Activity újralétrehozva (forgatás/konfiguráció) — nem küldünk analitikát")
        }
        super.onDestroy()
    }
}

Az isFinishing() ellenőrzése — fontos minta analitikához, naplózáshoz és munkamenet-adatok tisztításához. Elforgatáskor nem kell munkamenet-befejezési eseményeket küldeni — a felhasználó még mindig az alkalmazással dolgozik. A Google Analytics szerint az isFinishing() helytelen ellenőrzése a 40%-át teszi ki a hamis munkamenet-eseményeknek.

Gyakran Ismételt Kérdések

Lehetséges, hogy az onDestroy nem hívódik meg?

Igen, lehetséges — a rendszer általi folyamatmegszakításkor (process death), a felhasználó általi Force Stop-kor vagy vészhelyzeti befejezéskor. A Google adatai szerint az Activity befejezések körülbelül 5–8%-a az onDestroy meghívása nélkül történik. A fejlesztő nem támaszkodhat az onDestroy-ra kritikus adatok mentéséhez — használja az onPause-t vagy onSaveInstanceState-t.

Miben különbözik az onDestroy a finish()-től?

finish() — az Activity megsemmisítését elindító hívás. onDestroy — a visszahívás, amely a finish() végrehajtása során hívódik meg. A finish() kötelező az onDestroy meghívásához normál befejezéskor. A finish()-t a rendszer vagy a fejlesztő hívhatja meg, az onDestroy — csak rendszer-visszahívás.

Meg kell hívni a super.onDestroy()-t Fragment-ben?

Igen, feltétlenül mind az Activity-ben, mind a Fragment-ben. A super.onDestroy() biztosítja a ChildFragmentManager, LoaderManager és más rendszerkomponensek megfelelő tisztítását. A super.onDestroy() kihagyása memóriaszivárgáshoz és hibákhoz vezet a fragmentek visszaállításakor.

Mikor hívódik meg az onCleared() a ViewModel-ben az onDestroy-hoz képest?

Az onCleared() az Activity vagy Fragment onDestroy-je után hívódik meg, amikor a ViewModel már nem szükséges. Képernyőelforgatáskor az onCleared() nem hívódik meg — a ViewModel túléli az onDestroy-t. Sorrend: onDestroy Activity/Fragment → (ViewModelStore tisztítása) → onCleared().

Elindítható-e Service az onDestroy-ből?

Technikailag igen, de nem ajánlott. Az Activity az onDestroy után azonnal megsemmisül, és az elindított Service kontroll nélkül marad. Háttérfeladatokhoz használjon WorkManager-t késleltetéssel: a WorkManager garantálja a végrehajtást az Activity befejezése után is, és túléli a process death-et.

Összegzés

  • onDestroy — az Activity és Fragment életciklusának végső visszahívása, a komponens teljes megsemmisítése előtt hívódik meg.
  • Az onDestroy meghívása nem garantált process death esetén — körülbelül 5–8% befejezés nélküle történik.
  • Az onDestroy-ben fel kell szabadítani: hálózati callback-ek, socketek, fájladatfolyamok, BroadcastReceiver, ContentObserver.
  • A ViewModel.onCleared() az Activity onDestroy-je után hívódik meg — a viewModelScope automatikusan leáll.
  • Az onDestroyView a Fragment-ben (külön az onDestroy-től) — a megfelelő hely a View referenciák nullázására.
  • Az isFinishing() ellenőrzése az onDestroy-ben lehetővé teszi a finish() általi befejezés megkülönböztetését a konfigurációváltozások miatti újralétrehozástól.
  • Ne támaszkodjon az onDestroy-ra adatok mentéséhez — használja az onPause-t vagy onSaveInstanceState-t.

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is