Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handler fails to deliver a message or a Runnable to the main thread

I have an app with a two threads - main and data loader. When data loader finishes it posts a Runnable object to the main thread (as described in the DevGuide), but it never gets delivered and run.

Here's the basic code:

class MyApp extends Application
{
   public void onCreate()
   {
         LoaderThread t = new LoaderThread();
         t.start();
   }

   private class LoaderThread extends Thread
   {
        public void run()
        {
             SystemClock.sleep(2000);
             boolean res = m_handler.post(m_runnable);
             if(res)
                Log.d(TAG, "Posted Runnable");
        }
   }

   private final Handler m_handler = new Handler();
   private final Runnable m_runnable = new Runnable() {
             public void run()
             {
                 Log.d(TAG, "Hey, i'm runnable!");
             }
        }
}

Also it maybe important to note that I ran this code as a unit-test derived from an ApplicationTestCase:

class MyAppTest : public ApplicationTestCase
{
     public MyAppTest()
     {
          super(MyApp.class);
     }

     public void testLoading()
     {
          createApplication();
          // few asserts follow here...
     }
}

So this fails. Runnable never gets run() called, although the log indicates that it has been posted successfully. I also tried to send simple messages instead of posting runnable (m_handler.sendEmptyMessage(1) for example) - they never get delivered to handler's callback in the main thread.

What do I miss here?

Thanks in advance :)

like image 616
dimsuz Avatar asked Nov 14 '22 12:11

dimsuz


1 Answers

A Handler requires a Looper in order to work. The Looper provides a message queue required by the Handler.

All instances of Activity have a Looper as one is used to process UI Events, but you can create your instance of Looper elsewhere.

Have a look in your Log output to see if Android is complaining about the absence of a Looper.

If it is, you might be able to fix by add the following to the top of your onCreate() method:

Looper.prepare(); 
m_handler = new Handler();
Looper.run();

And remove the initialisation of m_handler from later in your code.

like image 96
Dave Webb Avatar answered Dec 15 '22 04:12

Dave Webb