withContext(Dispatchers.IO) – schwere Arbeit vom Main-Thread nehmen
Datei lesen oder ein Bild dekodieren blockiert den Main-Thread und ruckelt die UI. Mit withContext(Dispatchers.IO) schiebst du blockierende Arbeit sauber auf einen Hintergrund-Thread.
Auf Android läuft die UI auf dem Main-Thread. Alles, was dort blockiert – eine Datei lesen, ein Bild dekodieren, eine langsame Berechnung – lässt die Oberfläche ruckeln oder friert sie im schlimmsten Fall ein (ANR). Die saubere Lösung mit Coroutines: withContext(Dispatchers.IO) schiebt genau diesen Teil auf einen Hintergrund-Thread und gibt das Ergebnis zurück.
Blockierende Arbeit auslagern
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
class ThumbnailRepository(private val api: ApiService) {
// suspend-Funktion: der Aufrufer bleibt "main-safe",
// die blockierende Arbeit passiert auf einem IO-Thread.
suspend fun loadThumbnail(url: String): Bitmap = withContext(Dispatchers.IO) {
val bytes = api.download(url) // blockierend (Netzwerk/Datei)
BitmapFactory.decodeByteArray(bytes, 0, bytes.size) // blockierend (CPU/IO)
}
}Der Aufruf aus dem ViewModel bleibt schlank und main-sicher:
viewModelScope.launch {
val bitmap = repo.loadThumbnail(url) // wartet, ohne den Main-Thread zu blockieren
_thumbnail.value = bitmap
}Welchen Dispatcher wofür?
Dispatchers.IO– Netzwerk, Datei-/Datenbankzugriff, alles, was auf Ein-/Ausgabe wartet.Dispatchers.Default– reine CPU-Arbeit (Sortieren, Parsen großer Listen, Bildfilter).Dispatchers.Main– UI-Updates; hier landet der Code nachwithContextautomatisch wieder.
Zwei Dinge, die du dir merken solltest
withContextgibt einen Wert zurück – anders alslaunch. Das Ergebnis der letzten Zeile ist der Rückgabewert.- Retrofit und Room sind schon main-safe. Deren
suspend-Funktionen wechseln intern selbst den Thread – die musst du nicht zusätzlich inwithContext(Dispatchers.IO)wickeln. Der Wrapper ist für deinen eigenen blockierenden Code.
Wenn du eine flüssige Android-App in Kotlin & Compose brauchst – ohne Ruckler und ANRs – sprich mich an.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
callbackFlow – Listener-APIs in einen Flow verwandeln
Android steckt voller Callback-APIs mit `register`/`unregister`. Mit `callbackFlow` machst du daraus einen ganz normalen Flow – inklusive automatischem Abmelden, wenn niemand mehr zuhört.
kotlinx.serialization: JSON und data class ohne Handarbeit verbinden
Eine API antwortet mit JSON, deine App will eine data class. Dazwischen steht in vielen Projekten ein handgeschriebener Parser. Mit kotlinx.serialization sind es eine Annotation und eine Zeile – und ein Schalter, ohne den deine App beim nächsten API-Update abstürzt.
snapshotFlow in Jetpack Compose – aus Compose-Zustand einen Flow machen
Manchmal willst du auf einen Compose-Zustand reagieren wie auf einen Datenstrom – entprellen, kombinieren, sammeln. Genau das macht snapshotFlow. Ich zeige dir das an der häufigsten Aufgabe: mehr laden, wenn der Nutzer ans Listenende scrollt.