Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding what Looper is about in Android

I had to add Looper to the following code:

public class MyRunnable implements Runnable
{
  @Override
  public void run()
  {
      Looper.prepare();
      final Looper looper = Looper.myLooper();

      new Handler().postDelayed(
          new Runnable()
          {
            @Override
            public void run()
            {
              try
              {
              }
              catch (Exception ex)
              {
              }
              finally
              {
                looper.quit();
              }
            }
          }, 100);

      Looper.loop();
  }
}

Notice that I have a runnable inside a runnable. The nested runnable gets executed through a Handler. Initially I didn't have Looper but Android complained that I needed to call Looper.prepare before executing another thread.

I read up on Looper but it still seems kind of cryptic. It seems to act like some kind of internal messaging pipeline. It isn't clear to me why this is necessary since there are no messages going from my outer runnable to my inner runnable. Even though that is true, it seems that Android just makes the hard rule that if you call a thread from a thread, you MUST also call Looper.prepare. Even if I accept that as-is, it still doesn't help to understand why I need to call looper.loop and looper.quit. If I omit Looper.loop, my Handler never runs and that is what isn't clear. What does Looper.loop do that allows my Handler to run?

like image 701
Johann Avatar asked Jul 05 '13 06:07

Johann


People also ask

What is looper and handler in Android?

Looper is an abstraction over event loop (infinite loop which drains queue with events) and Handler is an abstraction to put/remove events into/from queue with events (which is drained by Looper) and handle these events when they are processed.

How do I get my MessageQueue from Looper?

It is a kind of worker that serves a MessageQueue for the current thread. Looper loops through a message queue and sends messages to corresponding threads to process. We can retrieve the MessageQueue for the current thread with Looper. myQueue() .

Where will your build artifact go once Looper is done building your application?

All of the artifacts involved in the build process are typically retained in the repository.

What is a runnable in Android?

Runnable is an interface which used for creating a new thread class similar to the thread class created by extending java. lang. Thread class. Only difference is, Runnable interface allows the class to extend other class (if required) to override/inherit functionality of some class.


2 Answers

Here is a great article about that.

Looper and Handler in Android

It comes along with a simple schema that leads to straight understanding of relationship between Loopers and Handler.

On this schema, we see that, within the same thread (depicted by the big rectangle), no matter how many handler you create, they will all be using the same Looper, i.e., the unique looper of this thread.

Handlers & Loopers

Note:

Looper have to be prepared to allow associated handler to process posted messages.

Android application, more precisely, android app UI thread(the main thread), already comes with a prepared looper (the mainLooper).

Here is how to Communicating with the UI Thread.

like image 185
Pascal Avatar answered Oct 11 '22 22:10

Pascal


A simple concept of the looper:

  1. Every worker thread you create and run ends once it performs its last operation.

  2. To prevent your thread termination you can start a loop by calling Looper.loop(), think of it as while(true){} statement. Before calling Looper.loop() you have to prepare the loop with Looper.prepare(), if it is not prepared yet. To terminate the loop and end your thread you will need to call looper.quit() on the looper.

Now for the notification you got from Android:

When you create a Handler in a thread, it will be bound to the thread it is created in and when you post runnable using this Handler, the code runs on the thread of the Handler.

So when the system saw that you want to run some code (especially 100ms in future) on a Handler that is bound to a thread that is going to die as soon as it finishes calling the post method it proposed to use Looper.loop() to prevent this thread from terminating and thus enabling you properly run the second Runnable in a still existing thread.

like image 25
MikeL Avatar answered Oct 11 '22 22:10

MikeL