withTimeout – hängende Coroutines nach X Sekunden abbrechen
Ein Netzwerkaufruf, der ewig hängt, blockiert deinen Ladezustand für immer. Mit `withTimeout` gibst du einer Coroutine eine Frist – läuft sie ab, bricht Kotlin sie sauber ab.
Ein Server antwortet mal nicht, das Mobilfunknetz ist lahm – und dein Ladespinner dreht sich in alle Ewigkeit. Damit ein Aufruf nicht unbegrenzt hängt, gibst du ihm mit withTimeout eine feste Frist.
Variante 1: Timeout als Fehler
withTimeout wirft eine TimeoutCancellationException, wenn der Block nicht rechtzeitig fertig wird. Die fängst du wie einen normalen Fehler ab:
suspend fun ladeProfil(): Profile = try {
withTimeout(5_000) { // maximal 5 Sekunden
api.getProfile() // ein suspend-Aufruf
}
} catch (e: TimeoutCancellationException) {
throw AppError("Zeitüberschreitung – bitte erneut versuchen")
}Variante 2: null statt Ausnahme
Oft willst du gar keinen Fehler, sondern einfach „nichts". Dafür gibt es withTimeoutOrNull – es liefert null, wenn die Zeit abläuft:
val profil: Profile? = withTimeoutOrNull(5_000) { api.getProfile() }
if (profil == null) {
// Fallback: Cache anzeigen, Hinweis einblenden …
}Wichtig: withTimeout bricht die Coroutine kooperativ ab. Das funktioniert nur, wenn dein Code auf Abbrüche reagiert – bei suspend-Funktionen aus kotlinx.coroutines (Retrofit, Ktor, delay) ist das automatisch der Fall. Reiner, blockierender Java-Code (Thread.sleep, ein synchroner Stream) merkt vom Timeout nichts; solche Aufrufe gehören ohnehin auf Dispatchers.IO und brauchen ein eigenes Zeitlimit.
Robuste Ladezustände sind der Unterschied zwischen „App hängt" und „App fühlt sich schnell an". Wenn du so etwas für deine Android-App brauchst: bymw.de.
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
rememberCoroutineScope – Coroutinen aus einem Klick in Jetpack Compose starten
LaunchedEffect ist super für Effekte beim Zusammenbau der UI – aber wie startest du eine Coroutine, wenn der Nutzer auf einen Button tippt? Dafür gibt es rememberCoroutineScope. Ich zeige den Unterschied und ein typisches Snackbar-Beispiel.
runCatching – Fehler in Kotlin funktional statt mit try/catch
Statt jeden Aufruf in try/catch zu wickeln, gibt dir `runCatching` ein Result zurück. Mit `map`, `getOrElse` und `onFailure` liest sich Fehlerbehandlung wie eine saubere Kette.
Flow.debounce – entprellte Live-Suche in Jetpack Compose
Eine Suche, die bei jedem Buchstaben eine Anfrage feuert, überlastet dein Backend. Mit `debounce` auf einem Flow wartest du eine kurze Pause ab und suchst erst dann – ideal fürs Suchfeld.