onPause: Was es ist, Activity-Zustand in Android speichern

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

onPause ist eine Android-Lebenszyklusmethode, die aufgerufen wird, wenn eine Activity den Eingabefokus verliert, aber auf dem Bildschirm teilweise sichtbar bleibt. Das System ruft onPause auf, bevor eine neue Activity in den Vordergrund tritt, beim Öffnen eines Dialogfelds, beim Drücken der Schaltfläche für zuletzt verwendete Apps oder bei einem eingehenden Anruf. Diese Methode ist der letzte garantierte Punkt zum Speichern von Benutzerdaten, da das System nach onStop und onDestroy den Prozess ohne zusätzliche Aufrufe beenden kann. Innerhalb von onPause speichert der Entwickler Entwürfe, pausiert Animationen, gibt die Kamera frei und schreibt den aktuellen UI-Zustand in SharedPreferences. Weitere Details zum vollständigen Activity-Lebenszyklus finden Sie im Artikel Activity Lifecycle.

Wichtige Erkenntnisse

  • onPause — Activity verliert Fokus, bleibt aber sichtbar; letzter garantierter Punkt zum Speichern von Daten
  • Zustand speichern — in onPause werden kritische Benutzerdaten gespeichert: Entwürfe, Formulartext, Fortschritt
  • Ressourcen freigeben — Kamera, Mikrofon, Videoplayer werden in onPause zur Übergabe an eine andere App freigegeben
  • Zeitlimit — onPause muss innerhalb von 100 ms abgeschlossen sein; Überschreitung verursacht ANR und verzögert den Übergang
  • SharedPreferences.apply() — asynchrones Schreiben in onPause; commit() blockiert den Thread und kann ANR verursachen
  • onPause vs onStop — onPause bei teilweiser Sichtbarkeit (Dialog), onStop bei vollständigem Ausblenden (andere Activity)
  • onSaveInstanceState — wird nach onPause aufgerufen, um temporären Zustand in einem Bundle zu speichern

Was ist onPause in Android

onPause ist die vierte Methode des Activity-Lebenszyklus, die aufgerufen wird, wenn der Bildschirm den Eingabefokus verliert, aber für den Benutzer teilweise sichtbar bleibt. Es handelt sich um einen «Übergangs»-Zustand zwischen dem aktiven Ausführen der App und dem Ausblenden. Das System ruft onPause in den folgenden Szenarien auf: Öffnen einer anderen Activity (ein neuer Bildschirm bedeckt den aktuellen teilweise), Erscheinen eines Dialogfensters (Dialog, PopupWindow, Snackbar lösen onPause nicht aus, DialogFragment jedoch schon), Drücken der Schaltfläche für zuletzt verwendete Apps, eingehender Anruf, Drücken der Ein-/Aus-Taste zum Sperren des Bildschirms.

Die Hauptaufgabe von onPause ist es, die App auf die Möglichkeit vorzubereiten, ausgeblendet oder zerstört zu werden. Dies ist der letzte Punkt im Lebenszyklus, an dem der Entwickler sicher sein kann, dass sein Code ausgeführt wird, bevor das System mit dem Übergang zu einer anderen Komponente fortfährt. Nach onPause ruft das System onStop auf (wenn die Activity vollständig ausgeblendet wird), wonach der Prozess jederzeit ohne zusätzliche Benachrichtigung beendet werden kann.

Laut der Android Developers-Dokumentation (2025) sollte onPause so leicht und schnell wie möglich sein. Solange onPause die Kontrolle nicht zurückgibt, kann das System die nächste Activity nicht starten — das bedeutet, dass der Benutzer eine Verzögerung beim Bildschirmübergang sieht. Google empfiehlt, onPause in weniger als 100 Millisekunden abzuschließen, und alle langen Operationen (Speichern in der Datenbank, Schreiben auf die Festplatte) sollten asynchron über Coroutinen oder apply() erfolgen.

onPause in Activity

In einer Activity wird die onPause-Methode jedes Mal aufgerufen, wenn der Bildschirm nicht mehr aktiv ist, aber teilweise weiter angezeigt werden kann. Ein typisches Beispiel: Der Benutzer öffnet die Karten-App, tippt auf Standort teilen, und ein Systemdialog zur App-Auswahl erscheint über den Karten. Die Karten-Activity erhält onPause, bleibt aber unter dem Dialog sichtbar. Wenn der Dialog geschlossen wird, erhält die Karten onResume, ohne dass onStart aufgerufen wird (der Bildschirm wurde nicht vollständig ausgeblendet).

kotlin
class NoteEditorActivity : AppCompatActivity() {
    private var binding: ActivityNoteEditorBinding? = null
    private val prefs by lazy {
        getSharedPreferences("note_drafts", Context.MODE_PRIVATE)
    }

    override fun onPause() {
        super.onPause()

        // Notizentwurf speichern — asynchron
        prefs.edit()
            .putString("draft_title", binding?.titleInput?.text.toString())
            .putString("draft_body", binding?.bodyInput?.text.toString())
            .putLong("draft_timestamp", System.currentTimeMillis())
            .apply()

        // Video pausieren
        binding?.videoPlayer?.pause()

        // Exklusive Ressourcen freigeben
        releaseCamera()
        releaseAudioFocus()
    }

    override fun onResume() {
        super.onResume()
        // Entwurf wiederherstellen
        binding?.titleInput?.setText(prefs.getString("draft_title", ""))
        binding?.bodyInput?.setText(prefs.getString("draft_body", ""))
        acquireCamera()
        acquireAudioFocus()
    }
}

Das Beispiel NoteEditorActivity demonstriert die korrekte Handhabung von onPause: Speichern eines Entwurfs in SharedPreferences über apply(), Anhalten einer Videodatei, Freigeben der Kamera und des Audiofokus. Jeder Aufruf ist leicht und schnell, ohne den UI-Thread lange genug zu blockieren, um ANR auszulösen. Beachten Sie die Reihenfolge: super.onPause() wird in der ersten Zeile aufgerufen — dies stellt sicher, dass die Systemlogik auch bei einer Ausnahme im Benutzercode ausgeführt wird.

Zustand in onPause speichern

onPause ist der letzte Punkt, an dem der Entwickler zuverlässig Benutzerdaten speichern kann, bevor die App ausgeblendet oder vom System beendet wird. Nach onStop kann das System den Prozess bei Speichermangel beenden, ohne onDestroy aufzurufen. Die Methode onSaveInstanceState() wird nach onPause aufgerufen, aber ihr Bundle ist nicht für die langfristige Speicherung gedacht — es lebt nur bis zum nächsten onCreate.

SharedPreferences mit apply()

SharedPreferences mit asynchronem apply() ist der optimale Weg, um kleine Datenmengen in onPause zu speichern. Im Gegensatz zu commit(), das synchron Daten auf die Festplatte schreibt und einen booleschen Wert zurückgibt, speichert apply() Daten sofort im Arbeitsspeicher und plant ein asynchrones Schreiben auf die Festplatte. Dies dauert weniger als 1 Millisekunde im UI-Thread, verglichen mit 10–100 Millisekunden bei commit().

kotlin
override fun onPause() {
    super.onPause()

    // ❌ Schlecht: Synchrones Schreiben blockiert den Thread
    // prefs.edit().putInt("score", score).commit()

    // ✅ Gut: Asynchrones Schreiben
    prefs.edit().putInt("score", score).apply()

    // Für komplexe Objekte — Caching im ViewModel
    viewModel.saveState()
}

Room und Coroutinen

Für strukturierte Daten (SQLite über Room) in onPause werden Coroutinen mit lifecycleScope verwendet. ViewModelScope bricht die Coroutine automatisch ab, wenn das ViewModel zerstört wird, und verhindert so Schreibvorgänge in einer geschlossenen Datenbank. Das Schreiben über Room mit Coroutinen dauert 5–15 Millisekunden und blockiert den UI-Thread nicht.

kotlin
// In ViewModel:
fun saveDraft(title: String, body: String) {
    viewModelScope.launch(Dispatchers.IO) {
        noteDao.insert(NoteDraft(title = title, body = body))
    }
}

// In Activity.onPause:
viewModel.saveDraft(
    binding?.titleInput?.text.toString(),
    binding?.bodyInput?.text.toString()
)

onPause in Fragment

onPause in Fragment wird aufgerufen, wenn das Fragment nicht mehr aktiv ist, aber sichtbar bleiben kann. Dies geschieht, wenn: ein Fragment durch ein anderes Fragment über FragmentTransaction ersetzt wird; ein Fragment nicht mehr die aktuelle Seite in einem ViewPager ist; die Activity, die das Fragment enthält, onPause erhält. Die Interaktion zwischen Activity-onPause und Fragment-onPause ist streng hierarchisch: zuerst erhält die Activity onPause, dann alle ihre Fragments.

kotlin
class MapFragment : Fragment() {
    private var mapController: MapController? = null

    override fun onPause() {
        super.onPause()
        mapController?.stopFollowMode()
        binding?.mapContainer?.alpha = 0.7f
    }

    override fun onResume() {
        super.onResume()
        binding?.mapContainer?.alpha = 1.0f
        if (isVisible) {
            mapController?.startFollowMode()
        }
    }
}

Besonderheiten bei der Arbeit mit Karten in onPause: Google Maps und Yandex Maps verbrauchen im aktiven Verfolgungsmodus erhebliche GPU-Ressourcen. Beim Verlust des Fokus ist es sinnvoll, die Kartenanimation zu deaktivieren und die Markeraktualisierungsfrequenz zu reduzieren, und bei Rückkehr des Fokus die volle Funktionalität wiederherzustellen. Dies verbessert die Leistung und reduziert den Stromverbrauch beim Wechseln zwischen Bildschirmen.

onPause vs onStop: Unterschied und Szenarien

Eine der häufigsten Verwechslungen bei Anfängern in der Android-Entwicklung ist das Nichtverstehen des Unterschieds zwischen onPause und onStop. Lassen Sie uns jedes Szenario untersuchen und die richtige Methode bestimmen.

SzenarioonPauseonStop
Öffnen eines DialogfeldsAufgerufenNicht aufgerufen
Öffnen einer neuen Activity (nicht transparent)AufgerufenAufgerufen
Drücken der Home-TasteAufgerufenAufgerufen
BildschirmsperreAufgerufenAufgerufen
Eingehender AnrufAufgerufenAufgerufen
Transparente Activity darüberAufgerufenNicht aufgerufen
Split Screen (halber Bildschirm)AufgerufenNicht aufgerufen
PiP (Bild-im-Bild)AufgerufenNicht aufgerufen

Die Hauptregel: onPause wird bei jedem Fokusverlust aufgerufen, onStop nur bei vollständigem Verlust der Sichtbarkeit. Wenn die Activity sichtbar bleibt (auch teilweise), wird onStop nicht aufgerufen. Dies ist kritisch wichtig für die Modi Split Screen, PiP und transparente Activity — hier funktionieren onPause/onResume, aber onStart/onStop nicht.

onPause Timing und Leistung

onPause ist die zeitkritischste Lebenszyklusmethode, da sie das Rendern der nächsten Activity blockiert. Das System wartet auf den Abschluss von onPause der aktuellen Activity, bevor es die neue anzeigt. Wenn onPause länger als 100 Millisekunden dauert, bemerkt der Benutzer eine Verzögerung beim Übergang; wenn es länger als 5 Sekunden dauert, zeigt das System einen ANR an.

Leistungsempfehlungen

Der Google Android Performance Guide (2025) gibt folgende Empfehlungen für onPause: Führen Sie keine Netzwerkanfragen durch — sie sollten abgebrochen oder zu WorkManager verschoben werden; schreiben Sie keine großen Dateien auf die Festplatte — verwenden Sie BufferedWriter in einem Hintergrundthread; führen Sie keine komplexen SQL-Abfragen aus — Room-Operationen sollten asynchron über Coroutinen erfolgen; vermeiden Sie die Erstellung neuer Objekte — die Garbage Collection in onPause verschlimmert die Verzögerung; verwenden Sie apply() anstelle von commit() für SharedPreferences.

kotlin
override fun onPause() {
    super.onPause()

    // ❌ Schlecht: HTTP-Anfrage blockiert die UI
    // val response = api.syncSave(data).execute()

    // ❌ Schlecht: Synchrones Schreiben in Datei
    // FileOutputStream(file).write(data)

    // ✅ Gut: Asynchrones Speichern
    lifecycleScope.launch {
        withContext(Dispatchers.IO) {
            api.saveData(data)
            fileDao.write(data)
        }
    }

    // ✅ Gut: Leichtes Schreiben in SharedPreferences
    prefs.edit().putString("key", value).apply()
}

Das Profiling von onPause über den Android Studio Profiler (CPU-Trace) zeigt die genaue Ausführungszeit. Wenn onPause mehr als 100 ms dauert, hebt der Profiler die Methode gelb hervor, bei mehr als 500 ms rot. In kommerziellen Projekten bei IT Sectr verwenden wir Macrobenchmark-Tests, die automatisch die Übergangszeit zwischen Activities überprüfen und Leistungsregressionen in der CI-Pipeline signalisieren.

Häufige Fehler in onPause

Selbst erfahrene Entwickler machen Fehler in onPause. Lassen Sie uns fünf typische Probleme und ihre Lösungen untersuchen.

Synchrones Datenbankschreiben

Das Aufrufen von Room DAO mit einer synchronen Abfrage (.executeAsObservable() ohne Coroutinen) in onPause blockiert den UI-Thread für 10–50 ms. Wenn gleichzeitig GC oder Schreibkonflikte auftreten, kann die Verzögerung 200–500 ms erreichen. Lösung: Verwenden Sie Coroutinen mit Dispatchers.IO oder apply() für SharedPreferences.

Registrieren neuer Listener

onPause ist nicht der Ort zum Registrieren von Listenern. Wenn Sie einen BroadcastReceiver in onPause registrieren, bleibt er aktiv, wenn die Activity nicht mehr sichtbar ist. Die Registrierung sollte nur in onStart/onResume erfolgen, und in onPause/onStop — nur die Abmeldung. Die Ausnahme sind Intent-gesteuerte APIs, die eine Registrierung vor dem Aufruf erfordern.

Ignorieren von Ausnahmen

Wenn in onPause eine unbehandelte Ausnahme auftritt, ruft das System onStop und onDestroy nicht auf. Die Activity bleibt in einem undefinierten Zustand hängen, und onResume kann bei der Rückkehr die freigegebenen Ressourcen möglicherweise nicht korrekt wiederherstellen. Lösung: Wickeln Sie kritische Operationen in try/catch mit Protokollierung über Log.e().

Speichern redundanter Daten

Es ist nicht nötig, in onPause Daten zu speichern, die leicht wiederhergestellt werden können. Zum Beispiel werden API-Anfrageergebnisse zum Zeitpunkt des Abrufs in Room oder DataStore zwischengespeichert, nicht in onPause. Speichern Sie nur das, was der Benutzer manuell eingegeben hat und nicht automatisch wiederhergestellt werden kann — Text in Feldern, ausgewählte Elemente, Bildlaufposition.

super.onPause() vergessen

super.onPause() sollte aufgerufen werden, aber im Gegensatz zu onCreate führt das Auslassen nicht sofort zu einem Absturz. Das System «vergibt» das Fehlen von super in onPause, aber die interne Zustandsmaschine gerät in einen inkorrekten Zustand. Der nächste onResume-Aufruf kann den Eingabefokus möglicherweise nicht wiederherstellen, sodass die Activity “eingefroren” bleibt. Rufen Sie super.onPause() immer so früh wie möglich auf.

Häufig gestellte Fragen

Was passiert, wenn finish() in onPause aufgerufen wird?

Der Aufruf von finish() in onPause beendet die Activity unmittelbar nach der Rückkehr aus der Methode. Dies ist ein gültiges Szenario, wenn der Bildschirm bei Fokusverlust geschlossen werden muss (z. B. ein Autorisierungsbildschirm beim Minimieren der App). Allerdings löst finish() den vollständigen Beendigungszyklus aus: onStop onDestroy, was eine Verzögerung zum Übergang hinzufügt. Verwenden Sie finish() in onPause nur, wenn es wirklich notwendig ist.

Wie unterscheidet sich onPause von onSaveInstanceState?

onPause dient zum Speichern von Daten, die die Prozessbeendigung überleben sollen (Entwürfe in SharedPreferences/Room). onSaveInstanceState dient zum Speichern des temporären UI-Zustands, der nur bis zum nächsten onCreate benötigt wird (Bildlaufposition, ausgewählter Tab). Das Bundle von onSaveInstanceState bleibt bei vollständiger Beendigung der App nicht erhalten — es existiert nur im Speicher. onPause-Daten werden auf der Festplatte gespeichert und überleben einen Neustart.

Kann ich in onPause einen Dialog öffnen?

Nicht empfohlen. Das Öffnen eines Dialogs oder Popups in onPause führt zu einer WindowLeakException, wenn die Activity bereits beendet wurde. Wenn Sie bei Fokusverlust eine Benachrichtigung anzeigen möchten, verwenden Sie NotificationManager (Systembenachrichtigungen) — das ist sicher und vom Benutzer erwartet. Für verzögerte Aktionen verwenden Sie AlarmManager oder WorkManager.

Warum ist onPause ein garantierter Speicherpunkt, onStop aber nicht?

onPause wird garantiert aufgerufen, bevor die Activity nicht mehr aktiv ist. onStop wird möglicherweise nicht aufgerufen, wenn das System den Prozess zur Speicherfreigabe beendet — in diesem Fall wird auch onDestroy nicht aufgerufen. onPause ist die einzige Methode nach onResume, die immer aufgerufen wird, unabhängig vom Grund des Fokusverlusts. Daher werden alle kritischen Daten genau in onPause gespeichert.

Wie teste ich onPause in Unit-Tests?

Zum Testen von onPause werden Robolectric oder FragmentScenario von AndroidX Test verwendet. FragmentScenario.create() moveToState(State.STARTED) moveToState(State.RESUMED) moveToState(State.STARTED) ruft nacheinander onPause auf. Anschließend wird überprüft, ob die Daten in SharedPreferences gespeichert wurden oder ob die Kamera über ein Mock-Objekt freigegeben wurde. Robolectric 4.12+ unterstützt die Emulation von onPause/onResume ohne physisches Gerät.

Zusammenfassung

  • onPause — Activity verliert Eingabefokus, bleibt aber teilweise sichtbar; letzter garantierter Punkt zum Speichern von Daten
  • Speichern — SharedPreferences.apply() oder Room über Coroutinen; commit() und synchrone Operationen sind verboten
  • Ressourcenfreigabe — Kamera, Audiofokus, Videoplayer werden in onPause zur Übergabe an eine andere App freigegeben
  • 100-ms-Limit — onPause blockiert das Rendern der nächsten Activity; Überschreitung des Limits verursacht ANR
  • onPause vs onStop — onPause bei Fokusverlust (Sichtbarkeit erhalten), onStop bei vollständigem Ausblenden
  • Fragment.onPause — hierarchischer Aufruf nach Activity.onPause; Besonderheiten bei Karten und ViewPager
  • Häufige Fehler — synchrones Schreiben, Listener-Registrierung, Ignorieren von try/catch, redundantes Speichern
  • super.onPause() — so früh wie möglich aufrufen; Auslassen verursacht keinen Absturz, bricht aber die Zustandsmaschine

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