How to create a Looper thread, then send it a message immediately?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Creating a Looper thread and sending it a message immediately is really about one timing constraint: the Handler cannot safely accept messages until the thread has prepared its Looper. If you post too early, you either get a NullPointerException, a handler without a prepared looper, or a race where the background thread is not ready yet.
The Core Problem
A Looper thread is usually created like this:
- start a new thread
- call
Looper.prepare() - create a
Handler - call
Looper.loop()
The difficulty is that the main thread may try to send a message before step 3 finishes.
That means the solution is not "send faster." The solution is to expose the handler only after initialization is complete.
The Simplest Correct Tool: HandlerThread
Android already provides HandlerThread, which solves exactly this setup problem.
getLooper() blocks until the looper is ready, so this is the easiest safe way to create a looper-backed worker and send a message right away.
Manual Looper Thread Initialization
If you need to build the thread manually, you must coordinate readiness. One way is using CountDownLatch:
Usage:
This works because getHandler() waits until the handler exists.
Why Direct Construction Often Fails
A common bad pattern looks like this:
This fails because start() only schedules the thread. It does not guarantee that run() has already reached Looper.prepare() and created the handler by the next line.
This is a classic cross-thread initialization race.
Cleaning Up the Thread
A looper thread should also be stopped cleanly when the work is done:
Or, for the manual version, call getLooper().quitSafely() from a controlled path. If you forget shutdown, the thread can stay alive and leak resources.
Choosing Between HandlerThread and Alternatives
Use HandlerThread when:
- you need one serial background queue
- you want message-based work
- legacy Android APIs already use handlers
For newer app code, coroutines, executors, or WorkManager are often easier to reason about. But if the requirement is specifically "looper thread plus messages," HandlerThread is still the clean answer.
Common Pitfalls
The main mistake is sending to the handler before it exists. Thread startup is asynchronous, so "I just started the thread" is not the same as "the looper is ready."
Another mistake is creating a Handler on a thread that never called Looper.prepare(). That triggers runtime errors because the handler has no message queue to bind to.
People also forget shutdown. A looper thread runs until it is told to quit, which can create leaks in long-lived components.
Finally, do not use sleep() to "wait for initialization." It is unreliable and unnecessary when proper coordination tools already exist.
Summary
- You can only send messages after the looper thread has prepared its
Looperand created itsHandler. - '
HandlerThreadis the simplest safe way to do this in Android.' - Manual looper threads need a readiness signal such as
CountDownLatch. - Sending immediately after
start()without synchronization is a race. - Always shut down looper threads cleanly when they are no longer needed.

