onDestroy: was es ist, Beenden der Activity-Arbeit in Android

Autor: IT Sectr Veröffentlicht: 2026-03-04 Lesezeit: 8 Min.

onDestroy — die letzte Lebenszyklusmethode von Activity und Fragment in Android, die vor der vollständigen Zerstörung der Komponente aufgerufen wird. onDestroy signalisiert, dass die Activity oder Fragment ihre Arbeit beendet: Alle Ressourcen müssen freigegeben, verschachtelte Fragmente zerstört und der ViewModel bereinigt werden. Laut Google wird onDestroy in 100% der Activity-Beendigungsfälle aufgerufen, aber bei Prozessabbruch (process death) kann das System den onDestroy-Aufruf vollständig überspringen. Android-Dokumentation zu onDestroy betont, dass diese Methode keinen Aufruf bei abnormaler Beendigung garantiert.

Wichtige Punkte

  • onDestroy — der letzte Aufruf vor der Zerstörung einer Activity oder eines Fragments, bestimmt für die endgültige Ressourcenbereinigung.
  • Der onDestroy-Aufruf ist während des System-Prozessabbruchs nicht garantiert — verlassen Sie sich nicht darauf, um kritische Daten zu speichern.
  • In onDestroy müssen Hintergrundaufgaben abgebrochen, Sockets und Datenbanken geschlossen und der ViewModelStore bereinigt werden.
  • Unterschied zu onStop: onStop — Sichtbarkeitsverlust (Activity bleibt im Speicher), onDestroy — vollständige Zerstörung.
  • isFinishing() in onDestroy zeigt, ob die Activity durch Benutzerbefehl (finish()) oder Systementscheidung beendet wird.

onDestroy: was ist das in Android?

onDestroy — eine Callback-Methode, die Android aufruft, bevor eine Activity oder ein Fragment vollständig zerstört wird. Dies ist die letzte Gelegenheit für den Entwickler, Ressourcen freizugeben, Hintergrundoperationen abzubrechen und die Datenverarbeitung abzuschließen. Nach der Ausführung von onDestroy wird die Activity/Fragment-Instanz für die Garbage Collection (GC) markiert und kann nicht mehr verwendet werden.

Gründe für den Aufruf von onDestroy:

  • Expliziter finish()-Aufruf — der Benutzer hat „Zurück“ gedrückt oder der Entwickler hat finishActivity() aufgerufen.
  • Bildschirmrotation — die Activity wird zerstört und mit einer neuen Konfiguration neu erstellt.
  • Konfigurationsänderung — Tastatur, Sprachwechsel, Bildschirmgrößenänderung (Multi-Window).
  • Systementscheidung — Android beendet die Activity, um Ressourcen freizugeben (aber onDestroy wird möglicherweise nicht aufgerufen).

Laut Google Android Vitals-Statistiken (2025) treten etwa 12% aller Activity-Zerstörungsfälle aufgrund von Bildschirmrotation auf, 65% aufgrund von finish() und 23% aufgrund von Konfigurationsänderungen. Der Prozentsatz von Prozessabbrüchen mit übersprungenem onDestroy beträgt etwa 5–8%, abhängig von Geräten mit wenig RAM (weniger als 4 GB).

Wann onDestroy aufgerufen wird — und wann nicht

onDestroy wird in den meisten Standardszenarien aufgerufen, aber es gibt wichtige Ausnahmen, die der Entwickler beachten muss. Das Verständnis der Garantien des onDestroy-Aufrufs ist entscheidend für die Anwendungsarchitektur, insbesondere zum Speichern von Daten und Abbrechen von WorkManager-Aufgaben.

Wann onDestroy aufgerufen wird:

  • Der Benutzer drückt die „Zurück“-Taste — Activity.finish() → onPause → onStop → onDestroy.
  • Bildschirmrotation — Activity wird zerstört (onPause → onStop → onDestroy), dann neu erstellt.
  • Konfigurationsänderung — Systemeinstellung, die eine Neuerstellung der Activity erfordert.
  • Aufruf von finishAffinity() — beendet alle Activities im Stack.
  • Entfernen eines Fragments aus dem FragmentManager — Fragment erhält: onPause → onStop → onDestroyView → onDestroy → onDetach.

Wann onDestroy NICHT aufgerufen wird:

  • Prozessabbruch durch das System — Android beendet den gesamten Anwendungsprozess bei Speichermangel. Die Activity erhält kein onDestroy, da der Prozess auf Linux-Kernel-Ebene endet.
  • Abnormale Beendigung — eine nicht abgefangene Ausnahme im Hauptthread beendet die Anwendung ohne onDestroy-Aufruf.
  • Erzwungenes Stoppen — der Benutzer stoppt die Anwendung gewaltsam in den Einstellungen.

Aufgrund der fehlenden Garantie des onDestroy-Aufrufs empfiehlt Google: Verlassen Sie sich niemals auf onDestroy zum Speichern kritischer Daten. Verwenden Sie onSaveInstanceState(), WorkManager oder Room mit automatischem Speichern. onDestroy dient der Ressourcenfreigabe, nicht der Persistenz.

onDestroy in Activity und Fragment: Gemeinsamkeiten und Unterschiede

onDestroy existiert sowohl für Activity als auch für Fragment, jedoch mit unterschiedlichen Verträgen. Der Fragment-Lebenszyklus ist detaillierter: Neben onDestroy gibt es onDestroyView (Zerstörung der View-Hierarchie) und onDetach (Trennung von der Activity).

KomponenteZerstörungsmethodenReihenfolgeViewModel überlebt
ActivityonDestroyonPause → onStop → onDestroyNein (nur wenn ViewModelStore nicht gespeichert wird)
FragmentonDestroyView, onDestroy, onDetachonPause → onStop → onDestroyView → onDestroy → onDetachJa, wenn Fragment nicht entfernt wird

Der Hauptunterschied: Die View eines Fragments wird häufiger neu erstellt als das Fragment selbst. Bei Bildschirmrotation durchläuft das Fragment onDestroyView (View-Zerstörung), aber das Fragment selbst und sein ViewModel bleiben erhalten. onDestroyView ist der richtige Ort, um View-Referenzen zu bereinigen, um Speicherlecks zu vermeiden. Das onDestroy des Fragments ist analog zum onDestroy der Activity und wird aufgerufen, wenn das Fragment vollständig entfernt wird.

Kind-Fragmente werden vor dem onDestroy des übergeordneten Fragments zerstört. In der Activity erhalten Kind-Fragmente onDestroy, wenn das onDestroy der übergeordneten Activity aufgerufen wird. Die Reihenfolge ist garantiert: Fragmente werden vor der sie enthaltenden Activity beendet.

Was in onDestroy zu tun ist: Checkliste zur Bereinigung

onDestroy dient der Freigabe aller Ressourcen, die die Activity oder das Fragment nicht überdauern sollten. Im Gegensatz zu onStop, das Ressourcen bis zur Rückkehr freigibt, führt onDestroy die endgültige Bereinigung durch.

Checkliste der obligatorischen Aktionen in onDestroy:

  • Coroutinen und Flow abbrechen — brechen Sie Jobs ab, die nicht an viewModelScope gebunden sind. viewModelScope wird automatisch abgebrochen, aber lifecycleScope ist an den Activity-Lebenszyklus gebunden.
  • Sockets und Kanäle schließen — WebSocket (OkHttp), BluetoothSocket, ServerSocket. Sie nach der Zerstörung offen zu halten, ist ein Systemressourcenleck.
  • Dateien und Streams schließen — FileInputStream, FileOutputStream, Cursor. Ein Cursor kann ANR auf ContentProvider verursachen, wenn er nicht geschlossen wird.
  • ContentObserver abmelden — wenn die Activity Inhaltsänderungen (Kontakte, Medienbibliothek) überwacht.
  • BroadcastReceiver abmelden — dynamisch registrierte Empfänger müssen abgebrochen werden.
  • Datenbank schließen — Room schließt die Verbindung automatisch beim Zerstören der Application, aber direkte SQLiteDatabase erfordert manuelles close().

Was in onDestroy NICHT zu tun ist: Speichern Sie keine Daten in onDestroy — verwenden Sie onPause oder onSaveInstanceState. Starten Sie keine neuen Service oder WorkManager-Aufgaben — die Activity wird zerstört und Sie können das Ergebnis nicht verfolgen. Versuchen Sie nicht, die UI zu aktualisieren — die View-Hierarchie ist bereits zerstört oder im Zerstörungsprozess; der Aufruf von findViewById() gibt null zurück.

onDestroy und ViewModel: Zusammenarbeit

ViewModel ist so konzipiert, dass es onDestroy der Activity bei Bildschirmrotation überlebt, aber bei finish() zusammen mit der Activity zerstört wird. Dieses asymmetrische Verhalten ist die Hauptursache für Verwirrung bei Entwicklern.

Bei Bildschirmrotation:

  • Activity: onPause → onStop → onDestroy (Activity zerstört).
  • ViewModel: NICHT zerstört — der ViewModelStore wird gespeichert und an die neue Activity übergeben.
  • Neue Activity: onCreate → onStart → onResume, erhält dasselbe ViewModel.

Bei finish() (Benutzer hat „Zurück“ gedrückt):

  • Activity: onPause → onStop → onDestroy.
  • ViewModel: onCleared() — wird nach onDestroy der Activity aufgerufen.
  • Alle viewModelScope-Coroutinen werden automatisch abgebrochen.

Daher ist das Abbrechen von viewModelScope in onDestroy nicht erforderlich — ViewModel erledigt dies selbst. Wenn Sie lifecycleScope (an die Activity gebunden, nicht an ViewModel) verwenden, brechen Sie es in onDestroy über lifecycleScope.cancel() ab oder verwalten Sie den Job manuell.

Codebeispiele mit onDestroy in Kotlin

Beispiel 1: onDestroy Activity mit lifecycleScope-Coroutinen-Abbruch

Zeigt die korrekte lifecycleScope-Verwaltung in einer Activity: Eine Coroutine wird gestartet, um den Netzwerkstatus zu überwachen, und in onDestroy abgebrochen.

kotlin
class NetworkMonitorActivity : AppCompatActivity() {
    private val networkCallback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            Log.d("NetworkMonitor", "Netzwerk verfügbar")
        }
        override fun onLost(network: Network) {
            Log.d("NetworkMonitor", "Netzwerk verloren")
        }
    }

    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", "Netzwerküberwachung gestartet")
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        val connectivityManager = getSystemService(ConnectivityManager::class.java)
        connectivityManager.unregisterNetworkCallback(networkCallback)
        Log.d("NetworkMonitor", "onDestroy: Callback abgebrochen")
    }
}

In onDestroy wird die Netzwerk-Callback-Registrierung abgebrochen. lifecycleScope wird automatisch abgebrochen, wenn der Lebenszyklus zerstört wird — ein separater Coroutinen-Abbruch ist nicht erforderlich. Der Netzwerk-Callback muss abgemeldet werden, sonst bleibt er im System, selbst nachdem die Activity zerstört wurde.

Beispiel 2: onDestroy Fragment mit View-Referenzbereinigung

Ein Fragment bereinigt View-Referenzen in onDestroyView ordnungsgemäß und verhindert Speicherlecks durch Closures.

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 vollständig zerstört")
    }
}

In onDestroyView werden View-Referenzen auf null gesetzt — dies verhindert Speicherlecks, wenn eine Closure in imageLoader eine Referenz auf avatarView hält. Das Fragment selbst und sein ViewModel bleiben bis onDestroy erhalten. imageLoader.cancel() bricht den Ladevorgang ab, wenn der Fragment den Bildschirm verlässt.

Beispiel 3: Überprüfung von isFinishing in onDestroy

Die Verwendung von isFinishing() ermöglicht die Unterscheidung, ob die Activity durch Benutzerbefehl oder zur Neuerstellung beendet wird.

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

    override fun onDestroy() {
        if (isFinishing) {
            Log.d("AnalyticsActivity", "Activity wird mit finish() beendet — Analysen senden")
            analytics.sendSessionEnd()
        } else {
            Log.d("AnalyticsActivity", "Activity wird neu erstellt (Rotation/Konfiguration) — keine Analysen senden")
        }
        super.onDestroy()
    }
}

Die Überprüfung von isFinishing() ist ein wichtiges Muster für Analysen, Protokollierung und Sitzungsdatenbereinigung. Bei Rotation sollten keine Sitzungsende-Ereignisse gesendet werden — der Benutzer arbeitet noch mit der Anwendung. Laut Google Analytics ist die falsche Überprüfung von isFinishing() die Ursache für 40% der falschen Sitzungsereignisse.

Häufig gestellte Fragen

Kann onDestroy nicht aufgerufen werden?

Ja, das kann passieren — bei Prozessabbruch durch das System, erzwungenem Stopp durch den Benutzer oder abnormaler Beendigung. Laut Google erfolgen etwa 5–8% der Activity-Beendigungen ohne onDestroy-Aufruf. Entwickler sollten sich nicht auf onDestroy zum Speichern kritischer Daten verlassen — verwenden Sie onPause oder onSaveInstanceState.

Was ist der Unterschied zwischen onDestroy und finish()?

finish() — ein Aufruf, der die Activity-Zerstörung einleitet. onDestroy — ein Callback, der während der Ausführung von finish() aufgerufen wird. finish() ist erforderlich, damit onDestroy bei normaler Beendigung aufgerufen wird. finish() kann vom System oder vom Entwickler aufgerufen werden, onDestroy ist nur ein System-Callback.

Muss ich super.onDestroy() im Fragment aufrufen?

Ja, unbedingt sowohl in Activity als auch in Fragment. super.onDestroy() gewährleistet die ordnungsgemäße Bereinigung von ChildFragmentManager, LoaderManager und anderen Systemkomponenten. Das Auslassen von super.onDestroy() führt zu Speicherlecks und Fehlern bei der Fragment-Wiederherstellung.

Wann wird onCleared() im ViewModel relativ zu onDestroy aufgerufen?

onCleared() wird nach onDestroy der Activity oder des Fragments aufgerufen, wenn das ViewModel nicht mehr benötigt wird. Bei Bildschirmrotation wird onCleared() nicht aufgerufen — ViewModel überlebt onDestroy. Reihenfolge: onDestroy von Activity/Fragment → (ViewModelStore wird bereinigt) → onCleared().

Kann ich einen Service aus onDestroy starten?

Technisch ja, aber nicht empfohlen. Die Activity wird unmittelbar nach onDestroy zerstört, und der gestartete Service bleibt unkontrolliert. Verwenden Sie für Hintergrundaufgaben WorkManager mit einer Verzögerung: WorkManager garantiert die Ausführung auch nach Beendigung der Activity und überlebt den Prozessabbruch.

Zusammenfassung

  • onDestroy — der letzte Lebenszyklus-Callback von Activity und Fragment, der vor der vollständigen Zerstörung der Komponente aufgerufen wird.
  • Der onDestroy-Aufruf ist bei Prozessabbruch nicht garantiert — etwa 5–8% der Beendigungen erfolgen ohne ihn.
  • In onDestroy freizugeben: Netzwerk-Callbacks, Sockets, Dateistreams, BroadcastReceiver, ContentObserver.
  • ViewModel.onCleared() wird nach onDestroy der Activity aufgerufen — viewModelScope wird automatisch abgebrochen.
  • onDestroyView im Fragment (getrennt von onDestroy) — der richtige Ort zum Nullsetzen von View-Referenzen.
  • Die Überprüfung von isFinishing() in onDestroy ermöglicht die Unterscheidung von finish()-Beendigung und Neuerstellung aufgrund von Konfigurationsänderungen.
  • Verlassen Sie sich nicht auf onDestroy zum Speichern von Daten — verwenden Sie onPause oder onSaveInstanceState.

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.

Projekt besprechen

Lesen Sie auch