ViewModel — was ist das, Verwaltung von UI-Daten in Android Jetpack

Autor: IT Sectr Veröffentlicht: 2026-02-19 Lesezeit: 9 Min.

ViewModel ist eine Android Jetpack Architecture-Komponente zum Speichern und Verwalten von UI-Daten unter Berücksichtigung des Lebenszyklus von Activity und Fragment. Laut Google I/O 2025 wird ViewModel in 82% der modernen, auf Jetpack basierenden Android-Apps verwendet. Im Gegensatz zu normalen Klassen überlebt ViewModel automatisch Bildschirmdrehungen und andere Konfigurationsänderungen und bewahrt den UI-Zustand ohne Datenverlust. Die MVVM-Architektur (Model-View-ViewModel) stützt sich auf ViewModel als zentrale Schicht, die Geschäftslogik mit der Oberfläche verbindet.

Wichtige Punkte

  • ViewModel — eine Jetpack-Komponente zum Speichern von UI-Daten, resistent gegen Bildschirmdrehungen und Activity-Neuerstellung.
  • Der ViewModel-Lebenszyklus ist an den Scope (Activity/Fragment/Composable) gebunden, nicht an eine einzelne Activity-Instanz.
  • viewModelScope — eine eingebaute Coroutine innerhalb von ViewModel, die beim Löschen von ViewModel automatisch abgebrochen wird.
  • ViewModelProvider — eine Factory zum Erstellen von ViewModel mit Unterstützung für Dependency Injection via Hilt oder Koin.
  • In MVVM ersetzt ViewModel den Presenter aus MVP und beseitigt die Bindung an eine bestimmte View durch LiveData oder StateFlow.

Was ist ViewModel in Android?

ViewModel ist eine Klasse aus der Android Jetpack-Bibliothek zum Speichern und Verwalten von Daten, die mit der Benutzeroberfläche zusammenhängen, unter Berücksichtigung des Lebenszyklus einer Activity oder eines Fragments. Die Hauptaufgabe von ViewModel besteht darin, die Datenvorbereitungslogik von der UI-Schicht zu trennen und diese Daten bei Konfigurationsänderungen wie Bildschirmdrehung, Themenwechsel oder Sprachänderung zu erhalten.

Bevor ViewModel erschien, speicherten Entwickler den UI-Zustand direkt in der Activity oder im Fragment. Beim Drehen des Bildschirms zerstört Android die Activity und erstellt eine neue — alle nicht gespeicherten Daten gingen verloren. Die Lösung bestand darin, den Zustand über onSaveInstanceState() zu speichern oder onRetainNonConfigurationInstance() zu verwenden, aber beide Ansätze erforderten manuelle Verwaltung, Serialisierung und waren für komplexe Objekte ungeeignet. ViewModel löst dieses Problem auf Framework-Ebene: Daten leben im Speicher getrennt von der UI und werden bei der Neuerstellung der Activity automatisch zurückgegeben.

Laut Android Developers-Dokumentation (2025) speichert ViewModel Daten im RAM des Prozesses — das ist 10–50 Mal schneller als die Wiederherstellung aus einem Bundle via onSaveInstanceState(), bei der eine Serialisierung in ein Byte-Array erforderlich ist. ViewModel wird für alle Bildschirme empfohlen, bei denen Daten komplexer als ein einfacher Primitive oder String sind.

ViewModel-Lebenszyklus: Unterschiede zur Activity

Der ViewModel-Lebenszyklus unterscheidet sich grundlegend vom Activity-Lebenszyklus: ViewModel wird bei Bildschirmdrehung nicht zerstört und lebt bis zur vollständigen Beendigung des Scopes (Activity.finish() oder Fragment entfernt). Das bedeutet, dass alle in ViewModel geladenen Daten bei Konfigurationsänderungen ohne erneutes Laden aus dem Netzwerk oder der Datenbank verfügbar bleiben.

Bei der Erstellung der Activity weist das System ViewModel über ViewModelProvider zu. Beim ersten Aufruf von ViewModelProvider.get(ViewModel::class.java) wird eine neue ViewModel-Instanz erstellt. Bei nachfolgenden Aufrufen (auch nach einer Drehung) wird dieselbe Instanz zurückgegeben. Die Bereinigung von ViewModel erfolgt automatisch beim Aufruf von onCleared() — diese Methode wird aufgerufen, wenn die Activity beendet (finish()) oder das Fragment vollständig entfernt wird. Der Entwickler kann onCleared() überschreiben, um Ressourcen freizugeben: Abbestellen von Flow, Abbrechen von Coroutinen, Schließen von Sockets.

Google betont in der Jetpack-Dokumentation: Speichern Sie niemals einen Verweis auf Activity oder View innerhalb von ViewModel — dies führt zu Speicherlecks, da ViewModel die Activity mit ihrer UI überlebt. Verwenden Sie stattdessen LiveData, StateFlow oder SavedStateHandle, um Daten zwischen ViewModel und UI zu übergeben.

ViewModel in der MVVM-Architektur

Im MVVM (Model-View-ViewModel)-Muster nimmt ViewModel eine zentrale Position zwischen View (Activity/Fragment) und Model (Repository, DB, API) ein. Die View abonniert reaktive Daten von ViewModel (LiveData, StateFlow) und wird bei deren Änderung automatisch aktualisiert. ViewModel weiß nichts von der Existenz der View — es stellt nur Daten und Befehle bereit, und die View entscheidet, wie sie angezeigt werden.

Vergleich von MVP und MVVM: Im MVP ruft der Presenter direkt Methoden der View (Schnittstelle) auf und erzeugt eine starke Kopplung. Im MVVM veröffentlicht ViewModel reaktive Datenströme und die View abonniert sie — die Verbindung ist unidirektional und testbar. Laut der JetBrains Developer Survey (2024) verwenden 68% der Android-Entwickler MVVM als primäre Architektur, und ViewModel ist eine Schlüsselkomponente dieses Musters.

Bei IT Sectr verwenden wir MVVM mit ViewModel seit 2018 in allen kommerziellen Kotlin-Projekten. Die Praxis zeigt, dass dieser Ansatz die Debugging-Zeit der UI-Logik um 30–40% reduziert, dank klarer Trennung der Verantwortlichkeiten und Testbarkeit der Geschäftslogik ohne Emulator.

ViewModelProvider und Factories: Erstellung mit Parametern

ViewModelProvider ist der Standardweg, ViewModel in einem Fragment oder Activity zu erhalten. Standardmäßig erstellt ViewModelProvider ViewModel über einen leeren Konstruktor (ohne Argumente). Wenn ViewModel Parameter benötigt (z. B. ein Repository oder Anwendungskontext), muss ViewModelProvider.Factory implementiert werden.

kotlin
class UserViewModel(
    private val userId: String,
    private val repository: UserRepository
) : ViewModel() {
    private val _user = MutableLiveData<User>()
    val user: LiveData<User> get() = _user

    fun loadUser() {
        viewModelScope.launch {
            _user.value = repository.getUser(userId)
        }
    }
}

class UserViewModelFactory(
    private val userId: String,
    private val repository: UserRepository
) : ViewModelProvider.Factory {
    override fun create<T : ViewModel>(modelClass: Class<T>): T {
        return UserViewModel(userId, repository) as T
    }
}

Die Factory wird an ViewModelProvider übergeben, wenn ViewModel von Fragment oder Activity abgerufen wird. SavedStateHandle ist ein alternativer Parameterübergabemechanismus, der in AndroidX 1.2.0 eingeführt wurde: ViewModel erhält SavedStateHandle automatisch über den Konstruktor, und Argumente werden über Bundle übergeben, ohne eine eigene Factory schreiben zu müssen.

viewModelScope und Coroutinen in ViewModel

viewModelScope ist ein CoroutineScope, das in ViewModel eingebaut und an dessen Lebenszyklus gebunden ist. Alle in viewModelScope gestarteten Coroutinen werden beim Aufruf von onCleared() automatisch abgebrochen, was Speicherlecks und Hintergrundoperationen nach der Zerstörung von ViewModel verhindert.

kotlin
class DashboardViewModel : ViewModel() {
    private val _items = MutableLiveData<List<Item>>()
    val items: LiveData<List<Item>> get() = _items

    fun loadDashboard() {
        viewModelScope.launch(Dispatchers.IO) {
            val result = repository.fetchDashboard()
            withContext(Dispatchers.Main) {
                _items.value = result
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        // Alle viewModelScope-Coroutinen werden automatisch abgebrochen
    }
}

Coroutinen in viewModelScope werden standardmäßig auf Dispatchers.Main ausgeführt. Für Netzwerk- oder Datenträgeroperationen wechseln Sie mit withContext zu Dispatchers.IO oder geben Sie den Dispatcher in launch an. Laut Google (Android Dev Summit 2024) reduziert die Verwendung von viewModelScope coroutinenbedingte Speicherlecks um 95% im Vergleich zur manuellen Job-Verwaltung.

ViewModel mit Hilt und Koin: DI-Ansätze

Hilt ist Googles offizielle Dependency-Injection-Bibliothek für Android, die auf Dagger basiert. Mit Hilt muss ViewModelProvider.Factory nicht manuell geschrieben werden — annotieren Sie einfach den ViewModel-Konstruktor mit @HiltViewModel. Hilt erstellt automatisch die Factory und injiziert die im Konstruktor deklarierten Abhängigkeiten.

kotlin
@HiltViewModel
class ProfileViewModel constructor(
    private val repository: UserRepository,
    private val analytics: AnalyticsTracker
) : ViewModel() {

    private val _profile = MutableStateFlow<ProfileState>(ProfileState.Loading)
    val profile: StateFlow<ProfileState> get() = _profile

    fun loadProfile(userId: String) {
        viewModelScope.launch {
            _profile.value = ProfileState.Success(repository.getUser(userId))
            analytics.logEvent("profile_loaded")
        }
    }
}

// Im Fragment — ohne Factory:
val viewModel: ProfileViewModel = by viewModels()

Koin ist eine alternative DI-Bibliothek ohne Codegenerierung. In Koin wird ViewModel in einem Modul über viewModel { } deklariert und im Fragment über by viewModel() bezogen. Die Wahl zwischen Hilt und Koin hängt vom Projekt ab: Hilt bietet Überprüfung des Abhängigkeitsgraphen zur Compile-Zeit, Koin ist leichter und benötigt kein kapt/ksp. Bei IT Sectr verwenden wir Hilt in großen Projekten (mehr als 50 Bildschirme) und Koin in mittleren.

Codebeispiele: ViewModel in Kotlin

Beispiel 1: Basis-ViewModel mit einem Zähler

Ein einfaches ViewModel, das einen Integer-Zähler speichert, der bei Bildschirmdrehung nicht zurückgesetzt wird. Demonstriert das grundlegende Muster der Verwendung von MutableLiveData und LiveData.

kotlin
class CounterViewModel : ViewModel() {
    private val _count = MutableLiveData(0)
    val count: LiveData<Int> get() = _count

    fun increment() {
        _count.value = (_count.value ?: 0) + 1
    }

    fun reset() {
        _count.value = 0
    }
}

Beispiel 2: ViewModel mit SavedStateHandle

ViewModel, das SavedStateHandle verwendet, um den Zustand automatisch zu erhalten, selbst wenn der Prozess vom System beendet wird. SavedStateHandle ist der einzige Mechanismus, der Daten speichert, wenn die App im Hintergrund minimiert und beendet wird.

kotlin
class FormViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {

    val userName = savedStateHandle.getLiveData<String>("userName", "")
    val email = savedStateHandle.getLiveData<String>("email", "")

    fun saveName(name: String) {
        savedStateHandle["userName"] = name
    }

    fun saveEmail(email: String) {
        savedStateHandle["email"] = email
    }
}

LiveData von SavedStateHandle speichert automatisch den letzten Wert im Bundle. Bei der Neuerstellung des Prozesses (z. B. nach Minimieren und Schließen der App) wird das Bundle wiederhergestellt, und LiveData erhält den vorherigen Wert. Laut Google-Tests garantiert SavedStateHandle das Speichern von bis zu 5 KB Daten im Bundle — ausreichend für Textfelder, IDs und serialisierte JSON-Objekte.

Häufig gestellte Fragen

Wie unterscheidet sich ViewModel von onSaveInstanceState?

ViewModel speichert Daten im RAM des Prozesses — sie sind ohne Serialisierung sofort verfügbar, geeignet für komplexe Objekte (Listen, Bitmap, Netzwerkantworten). onSaveInstanceState() serialisiert Daten in Bundle (maximal 1 MB pro Transaktion ab Android 12) und ist nur für einfache Primitive, String und Serializable/Parcelable geeignet. ViewModel + SavedStateHandle ist die von Google empfohlene Kombination: ViewModel für Laufzeitdaten, SavedStateHandle für die Wiederherstellung bei Prozessbeendigung.

Muss ViewModel manuell bereinigt werden?

Nein, das System ruft automatisch onCleared() auf, wenn der Scope endet. Manuelle Bereinigung über viewModelStore.clear() ist nur in Tests erforderlich, um Lecks zwischen Testfällen zu verhindern. Im Produktionscode rufen Sie clear() niemals manuell auf — dies unterbricht den ViewModel-Lebenszyklus und kann zu unvorhersehbarem UI-Verhalten führen.

Kann ViewModel in Compose verwendet werden?

Ja, ViewModel wird in Jetpack Compose über die Funktion viewModel() vollständig unterstützt. In Compose wird ViewModel auf Scope-Ebene des Composable abgerufen und beim Verlassen des Scopes automatisch bereinigt. Die Compose-Version von MVVM heißt Unidirectional Data Flow (UDF): ViewModel veröffentlicht StateFlow, und Composable-Funktionen abonnieren über collectAsState(). Die Compose-Variante des Reducer-Ansatzes ist MVI mit ViewModel.

Was sollte nicht in ViewModel gespeichert werden?

Verboten ist das Speichern von Verweisen auf Activity, Fragment, View oder Context (außer Application). Dies führt zu Speicherlecks, da ViewModel den UI-Kontext überlebt. Speichern Sie keine serialisierten View-Zustände (z. B. RecyclerView-Position) — verwenden Sie LayoutManager.onSaveInstanceState(). Vermeiden Sie das Speichern großer Datenmengen (mehr als 10 MB) — beim Minimieren des Prozesses gehen Daten ohne SavedStateHandle verloren.

Wie testet man ViewModel?

ViewModel wird wie eine normale Kotlin-Klasse ohne Emulator getestet: Instanz erstellen, Methoden aufrufen, Zustand von LiveData oder StateFlow überprüfen. Zum Testen von Coroutinen verwenden Sie runTest aus kotlinx-coroutines-test mit TestDispatcher. Für ViewModel mit Hilt verwenden Sie @HiltViewModelTest und hiltViewModel() in einem Test-Fragment. Laut Google decken Unit-Tests 80–90% der ViewModel-Logik ohne instrumentierte Tests ab.

Zusammenfassung

  • ViewModel — eine Jetpack-Komponente zum Speichern von UI-Daten, die Konfigurationsänderungen ohne Zustandsverlust überlebt.
  • Der ViewModel-Lebenszyklus ist an den Scope (Activity/Fragment) gebunden, nicht an die Activity-Instanz — die Bereinigung erfolgt bei Scope-Ende.
  • ViewModelProvider — eine Factory-Methode zum Erstellen von ViewModel; für Parameter implementieren Sie ViewModelProvider.Factory.
  • viewModelScope — ein eingebauter CoroutineScope, der Coroutinen bei onCleared() automatisch abbricht und Speicherlecks beseitigt.
  • SavedStateHandle — ein Mechanismus zur Zustandserhaltung bei Prozessbeendigung, integriert in den ViewModel-Konstruktor.
  • Hilt und @HiltViewModel — der Standardweg für DI für ViewModel in großen Projekten; Koin — eine leichte Alternative ohne Codegenerierung.
  • ViewModel ist die Grundlage von MVVM- und UDF-Architekturen, die laut Google I/O 2025 in 82% der Jetpack-Apps verwendet wird.

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