получить очередь сообщений основного обработчика и обработчик - PullRequest
4 голосов
/ 02 июля 2011

Как мне получить очередь сообщений основного потока из другого потока? Looper.getMainLooper () получает петлитель основного потока, но я не могу найти способ получить MessageQueue для петлителя другого потока. Кроме того, как мне получить обработчик для основного петлителя? Я не могу найти способ получить его.

Ответы [ 3 ]

3 голосов
/ 07 февраля 2012

@ r.v

У меня была похожая потребность. Я хотел знать, когда MessageQueue пусто, и когда я публикую что-то для этого, и я хочу знать, когда оно становится пустым, и ничего не остается сделать. Я посмотрел на MessageQueue.IdleHandler и обнаружил, что он не ведет себя так, как мне хотелось, я нашел другое решение.

В моем случае я хотел использовать механизм Looper / Handler для последовательного выполнения загрузки файлов. В основном каждая загрузка, которую я хочу выполнить, оборачивается в Runnable. Я хочу, чтобы работал только по одному, поэтому этот шаблон работает хорошо, без необходимости углубляться в гайки и болты более сложного резьбового раствора. Кроме того, я хотел знать, когда я впервые помещаю что-то в очередь, и она начинает свою работу, и хотел знать, когда это будет полностью сделано (очередь пуста).

Мне удалось использовать механизм сообщений обработчика для достижения этой цели. Сообщения обрабатываются последовательно с помощью Runnables, так что вы можете стратегически помещать сообщения в очередь, чтобы помочь вам узнать условия очереди. В отличие от Runnables в очереди обработчика, существуют некоторые возможности запроса и удаления для сообщений, которые в конечном итоге обеспечивают решение.

То, что я делаю, - это каждый раз, когда я добавляю исполняемый файл в обработчик (через Handler.post), я также удаляю все экземпляры пользовательского сообщения QUEUE_EMPTY, затем добавляю свежее сообщение QUEUE_EMPTY. Это гарантирует, что у меня есть QUEUE_EMPTY сообщение в конце очереди. Когда я сталкиваюсь с сообщением QUEUE_EMPTY в своем обработчике с подклассами, я знаю, что я нахожусь в конце очереди. Кроме того, если я не нахожу сообщение QUEUE_EMPTY в очереди при добавлении запускаемого объекта, я знаю, что очередь пуста, а поток простаивает.

Как быстро скажут некоторые, в этом решении есть некоторые реальные недостатки. Необходимость перебирать очередь для этих «маркерных» сообщений может быть реальной проблемой производительности, если в очереди находится большое количество записей. В моем случае я имею дело только с несколькими загрузками файлов за раз, поэтому любые потери производительности незначительны. Если у вас похожая ситуация, думаю, это довольно разумное решение. Было бы неплохо, чтобы Android SDK предоставил эти основные возможности MessageQueue. Я согласен, что в идеале вы не хотели бы связываться с MessageQueue, но знание того, когда оно бездействует / работает / пусто, кажется разумным, и я уверен, что существует множество сценариев, когда есть смысл знать эти вещи.

    class DownloaderThread extends Thread
{
    private static final int QUEUE_EMPTY = 9999;
    private MyHandler handler;

    @Override
    public void run()
    {
        try
        {
            Looper.prepare();
            handler = new MyHandler();
            Looper.loop();
        }
        catch (Throwable t)
        {
            Log.e(TAG, "halted due to an error", t);
        }
    }

    public void post(Runnable r)
    {
        if(!handler.hasMessages(QUEUE_EMPTY))
        {
            Log.v(TAG, "Download queue was empty.  First element being added.");
        }

        handler.post(r);
        handler.removeMessages(QUEUE_EMPTY);
        handler.sendEmptyMessage(QUEUE_EMPTY);
    }

    class MyHandler extends Handler
    {
        @Override
        public void handleMessage(Message msg)
        {
            if(msg.what == QUEUE_EMPTY)
            {
                Log.v(TAG, "Download runnable queue is empty!");
            }
        }
    }
};
1 голос
/ 12 января 2014

Используйте класс Handler для взаимодействия с очередью сообщений Looper.

Для взаимодействия с основной очередью сообщений потока,

Handler mainHandler = new Handler(Looper.getMainLooper(), new Callback() {

        @Override
        public boolean handleMessage(Message msg) {
            // TODO Auto-generated method stub
            return false;
        }
    });
mainHandler.post(...);
mainHandler.sendMessage(...);
mainHandler.removeMessage(...);

Теперь вы можете отправлять, удалять и получать сообщения.

0 голосов
/ 02 июля 2011

После того, как вы получите петли основных потоков, вы можете просто вызвать myQueue, чтобы получить основные потоки MessageQueue.

http://developer.android.com/reference/android/os/Looper.html#myQueue%28%29

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