6

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?

Johann
  • 27,536
  • 39
  • 165
  • 279
  • 1
    possible duplicate of [android: What is the purpose of Looper and how to use it?](http://stackoverflow.com/questions/7597742/android-what-is-the-purpose-of-looper-and-how-to-use-it). Yes, if you want to use Looper, then you must call Looper.prepare(). Alternatives to using a Looper include just creating normal (parallel) threads, or using AsyncTasks. Read the SO link I cited for a bit more background. 'Hope that helps... – paulsm4 Jul 05 '13 at 06:32
  • Sort of explains it. The biggest problem I see is referring to Runnables as "messages". These are not "messages" in the traditional sense of the programming world since a Runnable is an executable piece of code rather than simply data containing a message. Furthermore, the example you pointed to doesn't even include looper.quit which is required, nor does it indicate that Looper.loop will block indefinitely until looper.quit is called. Looper should be defined as nothing but a queue for executing multiple Runnables. – Johann Jul 05 '13 at 08:59

3 Answers3

8

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.

Community
  • 1
  • 1
Pascal
  • 15,257
  • 2
  • 52
  • 65
4

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.

MikeL
  • 5,385
  • 42
  • 41
1

I find the following tutorial very helpful in understanding the concept of looper .
Intro to looper and handler

oks16
  • 1,294
  • 11
  • 16