TL;DR: Don’t Freeze the Main Thread
Android’s main (UI) thread is like the maître d’ of an exclusive restaurant—clogs here and the whole experience tanks. Block it with network calls, heavy image decoding, or database crunching, and you’ll serve your users a side of ANRs and frustrated bug reports.
## Choosing the Right Tool
# Executors and Threads
Classic Java Thread
, Runnable
, ExecutorService
still work for simple, short-lived tasks, but they’re low-level and invite callback hell.
# Kotlin Coroutines
Gold standard since Android 8. Lightweight, structured concurrency, easy cancellation, and seamless main-thread dispatch. Replace most ad-hoc threading hacks with launch
, async
, and dispatchers.
# HandlerThread
Ideal for custom event loops—camera preview processing or continuous sensor data. Spawns a Looper on a background thread without callback tsunami.
# WorkManager
When you need guaranteed, deferrable tasks—like syncing data even if your app gets killed—WorkManager
is your apocalypse-resistant companion.
## Pitfalls to Avoid
# Updating UI Off-Thread
Only the main thread gets to touch UI elements. Crossing this line throws runtime exceptions or ninja bugs that appear only in production.
# Over-Threading
More threads ≠ better performance. Unbounded thread creation leads to context switching hell and memory thrashing. Pool threads via ExecutorService
or use coroutines’ dispatchers.
## Trends, Summary, and a Question
Kotlin coroutines dominate new projects; legacy tools (AsyncTask
, IntentService
) are relics. Jetpack’s lifecycle-aware APIs keep your code main-thread-safe. HandlerThread still shines for specialized loops; WorkManager wins for background guarantees. Overall, it’s surgical delegation—not raw horsepower—that makes apps slick. So… how are you keeping your main thread zen (or still making AsyncTask
happen)?