Handler() veraltet: Was nun? Ein Blick ins Jahr 2025
\n\nWenn Sie jemals für Android entwickelt haben, haben Sie mit Sicherheit Handler() verwendet, um zwischen Threads zu wechseln, verzögerte Aufgaben auszuführen oder die Benutzeroberfläche zu aktualisieren. Diese altbewährte Klasse begleitet uns seit den ersten Android-Versionen. Doch in den Jahren 2024-2025 hat Google den Konstruktor Handler() offiziell für deprecated (veraltet) erklärt. Tausende Entwickler auf Stack Overflow fragen sich: „What do I use now that Handler() is deprecated?“
In diesem Artikel werden wir untersuchen, warum Handler() veraltet ist, welche Alternativen Android im Jahr 2025 bietet, und vor allem, wie man modernen, sauberen Code in Kotlin schreibt, der bei Ihrem Teamleiter keine Tränen hervorruft. Los geht's!
Warum wurde Handler() als deprecated eingestuft?
\n\nDie Klasse Handler selbst ist nicht verschwunden. Veraltet ist lediglich der parameterlose Konstruktor (Handler()) und seine Überladungen, die implizit einen Looper aus dem aktuellen Thread erstellten. Das Problem ist, dass dieses Verhalten:
- \n
- Implizit und unsicher ist — wenn
Handler()in einem Hintergrund-Thread ohneLooperaufgerufen wird, führt dies zu einerRuntimeException. \n - Das Testen erschwert —
Handlerist eng mit dem Lebenszyklus von Threads verbunden, was Unit-Tests zu einer Herausforderung macht. \n - Moralisch veraltet ist — es gibt modernere und deklarativere Werkzeuge: Coroutines,
HandlerThread(explizit) undLiveData. \n
Google empfiehlt, entweder explizit einen Looper an den Konstruktor zu übergeben oder Alternativen zu verwenden. Schauen wir uns an, was genau den Platz eingenommen hat.
Alternative Nr. 1: Expliziter Looper (die einfachste Lösung)
\n\nWenn Sie nicht den gesamten Code umschreiben möchten, ist der schnellste Weg, die Veraltung zu beheben, die explizite Übergabe des Looper. Für den Haupt-Thread (UI-Thread) verwenden Sie Looper.getMainLooper().
// Alter Code (deprecated)\nval handler = Handler()\n\n// Neuer Code (2025)\nval handler = Handler(Looper.getMainLooper())\n\n// Oder für einen Hintergrund-Thread:\nval handler = Handler(Looper.myLooper()) // Achtung: kann null sein!\n\n\nDies löst nicht alle Probleme, entfernt aber die Compiler-Warnung. Für ernsthafte Projekte ist jedoch der Umstieg auf Coroutines besser.
\n\nAlternative Nr. 2: Kotlin Coroutines (von Google empfohlen)
\n\nSeit 2021 empfiehlt Google offiziell Kotlin Coroutines für asynchrone Operationen. Im Jahr 2025 ist dies bereits der Industriestandard. Warum sind Coroutines besser als Handler?
- \n
- Leichtgewichtig — Tausende von Coroutines blockieren keine Threads. \n
- Strukturierte Nebenläufigkeit — automatische Abbrechung bei Lebenszyklusende. \n
- Lesbarkeit — der Code sieht synchron aus, ohne Callbacks. \n
- Testbarkeit —
runBlockingundTestCoroutineDispatcherfür Unit-Tests. \n
So ersetzen Sie typische Handler-Aufgaben durch Coroutines:
Ersatz für postDelayed (verzögerte Aufgabe)
\n\n// Alter Weg mit Handler\nval handler = Handler(Looper.getMainLooper())\nhandler.postDelayed({\n // nach 2 Sekunden ausführen\n}, 2000)\n\n// Neuer Weg mit Coroutines\nlifecycleScope.launch {\n delay(2000) // blockiert den Thread nicht!\n // nach 2 Sekunden ausführen\n}\n\n\nErsatz für post (Wechsel zum UI-Thread)
\n\n// Alter Weg\nhandler.post {\n textView.text = "Hallo aus dem Hintergrund-Thread"\n}\n\n// Neuer Weg\nlifecycleScope.launch(Dispatchers.Main) {\n textView.text = "Hallo aus der Coroutine"\n}\n\n\nErsatz für removeCallbacks (Aufgabe abbrechen)
\n\n// Alter Weg\nval runnable = Runnable { /*...*/ }\nhandler.postD