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 — 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:
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).
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:
Wann onDestroy NICHT aufgerufen wird:
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 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).
| Komponente | Zerstörungsmethoden | Reihenfolge | ViewModel überlebt |
|---|---|---|---|
| Activity | onDestroy | onPause → onStop → onDestroy | Nein (nur wenn ViewModelStore nicht gespeichert wird) |
| Fragment | onDestroyView, onDestroy, onDetach | onPause → onStop → onDestroyView → onDestroy → onDetach | Ja, 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.
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:
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.
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:
Bei finish() (Benutzer hat „Zurück“ gedrückt):
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.
Zeigt die korrekte lifecycleScope-Verwaltung in einer Activity: Eine Coroutine wird gestartet, um den Netzwerkstatus zu überwachen, und in onDestroy abgebrochen.
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.
Ein Fragment bereinigt View-Referenzen in onDestroyView ordnungsgemäß und verhindert Speicherlecks durch Closures.
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.
Die Verwendung von isFinishing() ermöglicht die Unterscheidung, ob die Activity durch Benutzerbefehl oder zur Neuerstellung beendet wird.
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
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.
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.
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.
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().
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
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.
Lesen Sie auch