jaede
jaede

Reputation: 859

Android: Multiple handlers in one Activity

I have a single handler instance, and I try to post two Runnables. But what I observe is only the latest Toast is getting printed on the device.

Handler handler = new Handler(Looper.getMainLooper());
  handler.post(new Runnable() {
  @Override
  public void run() {
    try {
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    Toast.makeText(getApplicationContext(),"Showing from main activity",
        Toast.LENGTH_SHORT).show();

  }
});

handler.post(new Runnable() {
  @Override
  public void run() {
    try {
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    Toast.makeText(getApplicationContext(),"Showing from main activity new",
        Toast.LENGTH_SHORT).show();

  }
});

As per the explanation of Handler, it enqueues the runnables into the messages queue of the thread to which it it associated. Which means Both the toast should be displays in the order in which they are enqueued. Can someone please explain this?

Upvotes: 1

Views: 3269

Answers (1)

Aleksandr Medvedev
Aleksandr Medvedev

Reputation: 8998

When you make a Handler associated with the main looper, you should keep in mind that it's associated with the main thread. So calling Thread.sleep in the main thread is absolutely discouraged and should be avoided. Toasts use the UI thread as well, but you prevent it from appearing by freezing this thread. The steps happening in your code are as follow:

  1. The action to show first Toast is enqueued
  2. The action to show second Toast is enqueued

    // First action execution

  3. Make the thread sleep for 3 seconds
  4. Showing first toast is enqueued

    // Here first Toast should appear, but it doesn't happen right at the moment you called the method. Treat it as another message enqueued in the main looper

  5. Make the thread sleep for 3 seconds
  6. Showing second toast is enqueued
  7. First toast is shown
  8. Second toast is shown

In the end both toasts are shown, but you can see only the last one, because it's shown after the first and covers it. If you want to show two toasts with a short delay, use post delayed method, or something like:

    final Handler handler = new Handler(Looper.getMainLooper());
    final Context context = getApplicationContext();
    handler.post(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(context, "Showing from main activity",
                           Toast.LENGTH_SHORT).show();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(context, "Showing from main activity new",
                                   Toast.LENGTH_SHORT).show();
                }
            }, 3000);
        }
    });

Upvotes: 2

Related Questions