Обработчику не удается доставить сообщение или Runnable в основной поток - PullRequest
5 голосов
/ 18 февраля 2010

У меня есть приложение с двумя потоками - основной и загрузчик данных. Когда загрузчик данных завершает работу, он отправляет объект Runnable в основной поток (как описано в DevGuide), но он никогда не доставляется и не запускается.

Вот основной код:

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!");
             }
        }
}

Также может быть важно отметить, что я запустил этот код как модульный тест, полученный из ApplicationTestCase:

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

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

Так что это не получается. Runnable никогда не вызывается run (), хотя журнал указывает, что он был успешно опубликован. Я также пытался отправлять простые сообщения вместо публикации runnable (например, m_handler.sendEmptyMessage (1)) - они никогда не доставляются к обратному вызову обработчика в основном потоке.

Что мне здесь не хватает?

Заранее спасибо:)

Ответы [ 3 ]

1 голос
/ 18 февраля 2010

A Handler требует Looper для работы. Looper предоставляет очередь сообщений, необходимую для Handler.

Все экземпляры Activity имеют Looper, поскольку он используется для обработки событий пользовательского интерфейса, но вы можете создать свой экземпляр Looper в другом месте.

Загляните в свой вывод журнала, чтобы узнать, жалуется ли Android на отсутствие Looper.

Если это так, вы можете исправить это, добавив следующее в начало вашего onCreate() метода:

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

И удалите инициализацию m_handler из более позднего кода.

0 голосов
/ 29 сентября 2011

Альтернативой вызову Looper.prepare() является вызов new Handler(Looper.getMainLooper()).Проблема с вызовом Looper.prepare() заключается в том, что он вызовет исключение, когда в вашем потоке уже есть петлитель.Скорее всего, вы пишете код, который должен работать в разных средах, и это решение будет обрабатывать больше случаев.

См .: AsyncTask и Looper.prepare () error

0 голосов
/ 18 февраля 2010

Handler работает только в Activity AFAIK. Вы пытаетесь использовать его в Application.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...