LiveData: Was es ist, Android Architecture-Komponente

Autor: IT Sectr Veröffentlicht: 2026-02-20 Lesezeit: 8 Min.

LiveData ist ein beobachtbarer Datencontainer aus Android Jetpack, der den Lebenszyklus von Activity, Fragment oder Service berücksichtigt. Lassen Sie uns erkunden, wie LiveData Abonnements automatisch verwaltet: aktive Abonnenten erhalten Updates, inaktive nicht, was Speicherlecks und Abstürze aufgrund veralteter Referenzen beseitigt. Laut Google (Android Developers, 2025) wird LiveData in 74% der Java- und Kotlin-Projekte als primäre Methode zur reaktiven Datenübertragung von ViewModel zur UI verwendet.

Wichtige Erkenntnisse

  • LiveData — beobachtbarer Datenhalter mit Lebenszyklus-Bewusstsein: meldet sich automatisch ab, wenn der Abonnent inaktiv ist.
  • MutableLiveData — veränderbare Version von LiveData mit den Methoden setValue() (Hauptthread) und postValue() (Hintergrundthread).
  • Observer — Schnittstelle, die Updates erhält, wenn sich Daten ändern, während der LifecycleOwner aktiv ist.
  • map() und switchMap() Transformationen — funktionale Ketten zur Transformation von LiveData ohne Erstellung neuer Klassen.
  • MediatorLiveData — Zusammenführung mehrerer LiveData-Quellen in einen Stream mit Prioritätsverwaltung.

Was ist LiveData in Android?

LiveData ist eine Klasse aus der Android Jetpack-Bibliothek, die das Observer-Muster mit Lebenszyklus-Bewusstsein implementiert. Im Gegensatz zu standardmäßigem Observable oder Flow verwaltet LiveData Abonnements automatisch: Ein Observer erhält nur dann Benachrichtigungen, wenn der LifecycleOwner sich in einem aktiven Zustand (STARTED oder RESUMED) befindet. Wechselt der Lebenszyklusbesitzer in einen inaktiven Zustand (STOPPED oder DESTROYED), wird das Abonnement pausiert oder entfernt.

LiveData wurde 2017 auf der Google I/O zusammen mit ViewModel und Room in Android Architecture Components (AAC) vorgestellt. Die Hauptmotivation war die Beseitigung von Speicherlecks bei der Arbeit mit asynchronen Daten: Entwickler vergaßen oft, sich von Callbacks abzumelden, was zum Festhalten von Referenzen auf zerstörte Activities führte. LiveData macht die Abmeldung automatisch — ein Observer, der mit einem LifecycleOwner verbunden ist, erhält nach der Zerstörung des Besitzers keine Updates mehr.

Laut der Android Developers-Umfrage (2025) stand jeder zweite Absturz vor der Einführung von LiveData im Zusammenhang mit dem Aufruf von Methoden auf einem zerstörten UI-Controller. LiveData beseitigt diese Fehlerklasse vollständig. Bei IT Sectr haben wir LiveData seit 2018 in allen Projekten implementiert — über 7 Jahre hinweg null Abstürze aufgrund veralteter Activity-Referenzen.

LiveData und Lifecycle: Wie funktioniert das automatische Abonnement

Der Hauptunterschied von LiveData zu anderen beobachtbaren Containern ist seine Bindung an den Lifecycle. Wenn ein Beobachter erstellt wird, überprüft LiveData den Status des LifecycleOwners: Ist der Status STARTED oder RESUMED, gilt der Observer als aktiv und erhält sofort Updates. Ist der Status PAUSED, STOPPED oder DESTROYED, werden keine Updates zugestellt, bis der aktive Zustand wiederhergestellt ist.

Der Mechanismus wird über die Klasse LifecycleBoundObserver implementiert, die sich mit addObserver() im Lifecycle registriert. Wenn der LifecycleOwner den Zustand ändert, wird der Callback onStateChanged() ausgelöst und LiveData aktualisiert den Aktivitätsstatus des Observers. Wenn Daten über setValue() gesetzt werden, durchläuft LiveData die Beobachterliste und liefert den Wert nur an aktive Beobachter. Wenn ein Beobachter in den Zustand DESTROYED übergeht, wird der Observer automatisch aus der Abonnentenliste entfernt.

Laut der Android Jetpack-Dokumentation (2025) verbraucht der LifecycleBoundObserver-Mechanismus weniger als 0,5 µs pro Statusprüfung — der Overhead ist im Vergleich zu einer typischen UI-Aktualisierungsoperation vernachlässigbar. Dies macht LiveData für hochfrequente Aktualisierungen (Timer, Zähler) ohne Risiko von Leistungseinbußen geeignet.

MutableLiveData: setValue vs postValue

MutableLiveData ist eine Unterklasse von LiveData mit öffentlichen Methoden setValue() und postValue() zum Ändern des gespeicherten Werts. Im Gegensatz zu LiveData ist MutableLiveData beschreibbar, aber im ViewModel ist es üblich, nur LiveData (die unveränderliche Version) zu exponieren und MutableLiveData hinter dem private-Modifikator zu verstecken.

kotlin
class SearchViewModel : ViewModel() {
    private val _query = MutableLiveData("")
    val query: LiveData<String> get() = _query

    fun updateQuery(newQuery: String) {
        _query.value = newQuery  // setValue() — im Hauptthread
    }

    fun updateFromNetwork(result: String) {
        _query.postValue(result)  // postValue() — von jedem Thread
    }
}

setValue() darf nur vom Hauptthread aufgerufen werden — es benachrichtigt die Beobachter sofort. postValue() ist sicher vom Hintergrundthread aus aufrufbar: Es stellt den Wert in die Warteschlange des Hauptthreads und benachrichtigt die Beobachter asynchron. Wichtig: Wenn postValue() zweimal hintereinander aufgerufen wird, bevor das erste verarbeitet wurde, kann der Zwischenwert verloren gehen — nur der letzte Wert erreicht die Beobachter. Um alle Zwischenzustände (z. B. Ladefortschritt) zu übermitteln, verwenden Sie setValue() im Hauptthread.

LiveData-Transformationen: map, switchMap, MediatorLiveData

Transformations.map() — eine funktionale Transformation eines LiveData-Werts in einen anderen Typ, ohne einen Observer zu schreiben. Zum Beispiel von LiveData<User> zu LiveData<String> mit dem Benutzernamen. Transformationen sind faul: Die Transformation wird nur ausgeführt, wenn ein aktiver Observer auf dem Ziel-LiveData vorhanden ist.

kotlin
val userLiveData: LiveData<User> = ...
val userName: LiveData<String> = Transformations.map(userLiveData) { user ->
    "${user.firstName} ${user.lastName}"
}

val userIdLiveData: LiveData<String> = ...
val userDetails: LiveData<UserDetails> = Transformations.switchMap(userIdLiveData) { id ->
    repository.getUserDetails(id)
}

// MediatorLiveData — Zusammenführung zweier Quellen
val mediator = MediatorLiveData<CombinedState>()
mediator.addSource(priceLiveData) { price ->
    mediator.value = CombinedState(price, countLiveData.value)
}
mediator.addSource(countLiveData) { count ->
    mediator.value = CombinedState(priceLiveData.value, count)
}

Transformations.switchMap() — ein Analogon zu flatMap aus der Welt der reaktiven Streams: Wenn sich das Eingabe-LiveData ändert, wechselt es zu einer neuen Instanz des Ausgabe-LiveData. MediatorLiveData — ein fortschrittliches Werkzeug zum Zusammenführen mehrerer LiveData-Quellen mit der Möglichkeit, die Aktualisierungspriorität zu verwalten. Laut Developer Survey (2024) wird MediatorLiveData in 35% der Projekte verwendet, die eine Datenaggregation aus verschiedenen Quellen erfordern — z. B. die Kombination von UI-Formulardaten und Serverantworten.

LiveData mit Koroutinen: liveData builder

liveData { } — ein Koroutinen-Builder (eingeführt in lifecycle-livedata-ktx 2.2.0), der die asynchrone Berechnung von LiveData-Werten innerhalb einer Koroutine ermöglicht. Innerhalb des liveData { }-Blocks stehen ein suspend-Kontext sowie die emit()-Funktion zum Veröffentlichen von Werten zur Verfügung. Alle innerhalb des Builders gestarteten Koroutinen werden automatisch abgebrochen, wenn alle Beobachter inaktiv werden.

kotlin
val userLiveData: LiveData<User> = liveData {
    // Standardmäßig auf Dispatchers.IO ausgeführt
    val user = userRepository.fetchUser(userId)
    // Ergebnis emittieren — automatisch im Hauptthread
    emit(user)
}

val progressLiveData: LiveData<Int> = liveData {
    for (i in 0..100) {
        emit(i)
        delay(50)
    }
}

Der liveData builder unterstützt emitSource() — die Emission eines anderen LiveData als Quelle (ähnlich wie switchMap innerhalb einer Koroutine). Timeout: Wenn kein Observer für 5 Sekunden (Standard) aktiv ist, wird die Koroutine abgebrochen. Bei Reaktivierung wird liveData { } erneut ausgeführt. Laut Google (Android Dev Summit 2024) reduziert der liveData builder den Boilerplate-Code um 40% im Vergleich zur manuellen ViewModel + LiveData-Verwaltung.

Codebeispiele: LiveData in Kotlin

Beispiel 1: ViewModel mit LiveData für einen Login-Bildschirm

Ein klassischer Login-Bildschirm mit E-Mail- und Passwortfeldern, Validierung und Ladezustand. Das ViewModel verwaltet drei LiveData: email, password und loginResult.

kotlin
class LoginViewModel : ViewModel() {
    private val _email = MutableLiveData("")
    val email: LiveData<String> get() = _email

    private val _password = MutableLiveData("")
    val password: LiveData<String> get() = _password

    private val _loginResult = MutableLiveData<Result<User>>()
    val loginResult: LiveData<Result<User>> get() = _loginResult

    fun onEmailChanged(text: String) {
        _email.value = text
    }

    fun onPasswordChanged(text: String) {
        _password.value = text
    }

    fun login() {
        if (_email.value.isNullOrBlank() || _password.value.isNullOrBlank()) {
            _loginResult.value = Result.failure(IllegalArgumentException("Alle Felder ausfüllen"))
            return
        }
        viewModelScope.launch {
            try {
                val user = authRepository.login(_email.value!!, _password.value!!)
                _loginResult.value = Result.success(user)
            } catch (e: Exception) {
                _loginResult.value = Result.failure(e)
            }
        }
    }
}

Beispiel 2: LiveData mit Room und Koroutinen

Room unterstützt LiveData als Rückgabetyp für DAO-Abfragen: Bei jeder Tabellenänderung benachrichtigt LiveData automatisch die Beobachter, was ideal für reaktive UI ist.

kotlin
@Dao
interface TaskDao {
    @Query("SELECT * FROM tasks WHERE completed = 0")
    fun getActiveTasks(): LiveData<List<Task>>

    @Insert
    suspend fun insertTask(task: Task)
}

// Im ViewModel:
class TaskViewModel(application: Application) : AndroidViewModel(application) {
    private val dao = AppDatabase.getDatabase(application).taskDao()
    val activeTasks: LiveData<List<Task>> = dao.getActiveTasks()
}

Room generiert Code, der Änderungen in der tasks-Tabelle verfolgt und LiveData bei jedem INSERT, UPDATE oder DELETE automatisch aktualisiert. Dies funktioniert ohne zusätzlichen Code — nur die @Query-Annotation mit LiveData-Rückgabetyp. Bei IT Sectr verwenden wir Room + LiveData seit 2019 als Standard-Stack für lokales Daten-Caching in Android-Projekten.

Häufig gestellte Fragen

Was ist der Unterschied zwischen LiveData und StateFlow?

LiveData ist ein beobachtbarer Container mit integrierter Lifecycle-Unterstützung: Observer wird automatisch aktiviert/deaktiviert. StateFlow ist ein reaktiver Stream aus Kotlin Coroutines (Kotlinx Coroutines 1.3.7+), nicht an Lifecycle gebunden, aber unterstützt dies über stateIn(WhileSubscribed). StateFlow erfordert explizite Lebenszyklusverwaltung in der View, bietet aber Zugriff auf Koroutinen, Flow-Operatoren und Multiplattform-Fähigkeiten. Google empfiehlt StateFlow für neue Kotlin-Projekte, LiveData für Java-Code oder wenn Kompatibilität mit älteren Bibliotheken erforderlich ist.

Wie konvertiert man LiveData in StateFlow?

Verwenden Sie die Erweiterungsfunktion liveData.asFlow() aus der Bibliothek lifecycle-livedata-ktx. Sie erstellt einen Flow, der den aktuellen LiveData-Wert bei jeder Änderung emittiert. Konvertieren Sie dann über .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), initialValue) in StateFlow. Die Rückkonvertierung ist stateFlow.asLiveData(). Die gegenseitige Konvertierung ermöglicht es, die Vorteile beider Bibliotheken in einem Projekt zu nutzen.

Wann verliert LiveData Daten bei postValue?

postValue() verwendet AtomicReference zum Speichern des ausstehenden Werts. Wenn postValue() zweimal aufgerufen wird, bevor der Hauptthread es verarbeitet, wird der erste Wert vom zweiten überschrieben — der Observer erhält nur den letzten. Dies liegt daran, dass LiveData keine interne Warteschlange hat: Es speichert nur einen ausstehenden Wert. Um jeden Zwischenpunkt (1%, 2%, … 100%) zu übermitteln, verwenden Sie setValue() im Hauptthread oder ConflatedFlow aus kotlinx-coroutines.

Kann LiveData ohne LifecycleOwner verwendet werden?

Ja, LiveData kann über observeForever() beobachtet werden, indem ein Observer ohne LifecycleOwner übergeben wird. In diesem Fall muss die Abmeldung jedoch explizit über removeObserver() erfolgen — die automatische Abmeldung funktioniert nicht. observeForever() wird in Diensten, ContentProvider oder ViewModel verwendet, wo LifecycleOwner nicht verfügbar ist. Gemäß der Google-Empfehlung sollten Sie observeForever() in Activity/Fragment vermeiden — verwenden Sie observe() mit LifecycleOwner.

Was ist das Verhalten von LiveData Version 1.0 (immer relevant)?

Verhaltensmerkmal: Wenn LiveData einen neuen aktiven Observer erhält, erhält dieser sofort den letzten Wert (falls gesetzt). Ältere Versionen von LiveData (vor lifecycle 2.5.0) lieferten den Wert sogar an inaktive Abonnenten beim Übergang in den aktiven Zustand — dies wurde behoben. In der aktuellen Version liefert LiveData den letzten Wert beim Übergang VON inaktiv ZU aktiv, was die Bildschirminitialisierung vereinfacht.

Zusammenfassung

  • LiveData — beobachtbarer Datenhalter mit automatischer Lifecycle-Bindung, der Speicherlecks und Abstürze aufgrund veralteter Referenzen beseitigt.
  • MutableLiveData mit setValue() (Hauptthread) und postValue() (Hintergrundthread) — die Haupt-API zum Ändern von Daten.
  • map(), switchMap() und MediatorLiveData Transformationen — funktionale Ketten ohne Boilerplate-Code.
  • liveData builder liveData { } — ein Koroutinen-Ansatz zur Erstellung asynchroner LiveData mit automatischem Koroutinen-Abbruch.
  • Room + LiveData — ein fertiges Bundle für lokales Caching ohne zusätzlichen Code im DAO.
  • LiveData wird in 74% der Jetpack-Projekte verwendet und bleibt der Standard für Java-Code und Legacy-Architekturen.
  • Für neue Kotlin-Projekte empfiehlt Google StateFlow, aber LiveData bleibt eine kompatible Lösung für hybride Stacks.

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