Looper & Handler (Pipeline Thread)
  • executes tasks on a single Thread in a sequential manner
  • a wrapper for these 2 classes see: HandlerThread

Loopers & Handlers basically implement a common concurrency pattern called Pipeline Thread. Here’s how it works:

  • the Pipeline Thread holds a queue of tasks which are just some units of work that can be executed or processed.
  • other threads can safely push new tasks into the Pipeline Thread’s queue at any time.
  • the Pipeline Thread processes the queued tasks one after another. If there are no tasks queued, it blocks until a task appears in the queue.
  • sometimes tasks can called messages and other names

their responsibility:

  • Looper is a class that turns a thread into a Pipeline Thread
  • Handler gives you a mechanism to push tasks into Pipeline Thread from any other threads

Example

Here’s what you should put into a Thread’s run() method to turn it into a Pipeline Thread and to create a Handler so that other threads can assign tasks to it

@Override
public void run() {
	try {
		// preparing a looper on current thread			
		// the current thread is being detected implicitly
		Looper.prepare();
 
		// now, the handler will automatically bind to the
		// Looper that is attached to the current thread
		// You don't need to specify the Looper explicitly
		handler = new Handler();
			
		// After the following line the thread will start
		// running the message loop and will not normally
		// exit the loop unless a problem happens or you
		// quit() the looper (see below)
		Looper.loop();
	} catch (Throwable t) {
		Log.e(TAG, "halted due to an error", t);
	} 
}

After that, you can just pass the handler to any other thread. It has a thread-safe interface that includes many operations, but the most straightforward ones are postMessage() and its relatives

For example, imagine another thread has a reference to the handler that was created in our Pipeline Thread. Here’s how that other thread can schedule an operation to be executed in the Pipeline Thread:

handler.post(new Runnable() {
	@Override
	public void run() { 
		// this will be done in the Pipeline Thread 
	}
});

Android UI Thread

By the way, the UI thread has a Looper created for it implicitly, so you can just create a Handler in activity’s onCreate() and it will work fine:

@Override
public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	// Create the Handler. It will implicitly bind to the Looper
	// that is internally created for this thread (since it is the UI thread)
	handler = new Handler();
}