开发者

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

开发者 https://www.devze.com 2022-12-21 01:04 出处:网络
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.

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 exa开发者_C百科mple) - they never get delivered to handler's callback in the main thread.

What do I miss here?

Thanks in advance :)


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.


Handler only works in an Activity AFAIK. You are attempting to use it in an Application.


An alternative to calling Looper.prepare() is to call new Handler(Looper.getMainLooper()). The problem with calling Looper.prepare() is that it will throw an exception when there is already a looper on your thread. Chances are you are writing code that has to run under different environments and this solution will handle more cases.

See: AsyncTask and Looper.prepare() error

0

精彩评论

暂无评论...
验证码 换一张
取 消