Looper, Handler & Threading Interview Questions

ANDROID › System

Walk me through what's actually happening under the hood when you call handler.post {} from a background thread and that code runs on the UI thread a moment later. Why can't you just mutate a View directly from that background thread instead?

What a strong answer covers: The post enqueues a Message wrapping the Runnable, targeted at the Handler, onto the main thread's MessageQueue; Looper.loop() on the main thread pumps that queue and dispatches the message back to the Handler's handleMessage/callback on the thread the Looper belongs to. The View system has no locking and assumes single-threaded access, so mutating a View from another thread risks races and inconsistent state, which is why everything funnels through the main thread's own queue instead of touching views directly.

When would you actually reach for a HandlerThread with a Handler over coroutines, in a codebase that's otherwise fully on kotlinx.coroutines?

What a strong answer covers: Almost never for new application logic, since Dispatchers.Default/IO give you structured concurrency on a shared pool. Legitimate cases are interfacing with legacy Handler-based APIs that require a single dedicated thread with its own Looper and strict FIFO message ordering, like MediaCodec callbacks or a SurfaceView rendering thread, where the API contract is built around a persistent thread identity rather than a rotating pool.

Your app has a small but persistent rate of ANRs in production that you can't reproduce locally, and StrictMode isn't catching anything. How would you narrow down the root cause?

What a strong answer covers: Pull the actual ANR traces from Play Console vitals or a Perfetto/system trace to see what the main thread's stack was doing at the moment of the freeze, since the blocker is often not obvious application code but a slow Binder call to another process, ContentProvider initialization, or disk I/O triggered indirectly. A common trap is assuming ANRs always mean your code is looping; GC pauses stealing scheduler time and lock contention with a background thread holding a lock the main thread needs are just as common and won't show up in StrictMode's disk/network checks.

Back to Looper, Handler & Threading