Как Android / DalvikVM обрабатывает обработчики? - PullRequest
2 голосов
/ 10 января 2011

Мне интересно, как обрабатываются обработчики в Android / DalvikVM.Я пишу приложение для Android, и в одном классе у меня есть метод Handler, который получает сообщения от другого класса.Будет ли метод Handler действовать как Thread и будет асинхронным с методом run () в том же классе, или он будет ждать, пока строка кода в методе run () не будет завершена (своего рода атомарная операция)?Или что-то еще?

Мне интересно, потому что я хочу добавить сообщения в очередь в методе Handler, а также обработать и удалить их в методе run () (производитель-потребитель).

Моя структура кода:

public class Parser implements Runnable {
    public void run() {
            while(true) {
            // Remove a byte from the ring buffer and parse it
            byte b = Ringbuffer_read();
            // Parse
        try {
                Thread.sleep(40);
            } catch (InterruptedException e) {}
           }
    }

    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case MESSAGE_READ:
                // Store all the received bytes in the ring buffer
                for (int i = 0; i < msg.arg1; i++) {
                    Ringbuffer_store(((byte[]) msg.obj)[i]);
                }
                break;
            }
        }
    };
}

Когда будет выполняться код в обработчике?Прерывает ли он код в методе run () в любой момент?Нужно ли иметь какие-то синхронизации или семафоры или что-то подобное в коде метода run () и обработчика, чтобы я не повредил свой буфер?

1 Ответ

4 голосов
/ 11 января 2011

Android Handler ассоциируется с тем потоком, в котором он создан (при условии, что поток уже имеет петлитель).По умолчанию в Android обратные вызовы выполняются в потоке с именем «main», который также называется потоком пользовательского интерфейса.Независимо от того, из какого потока вызывается метод post из метода handleMessage, он будет вызываться из потока, в котором был создан обработчик (обычно это «основной» поток).Поскольку метод handleMessage всегда вызывается в одном и том же потоке, за один раз будет обрабатываться только одно сообщение.

Если в вашем плане должен быть только один потребитель, то Handler является хорошим выбором.Вам не нужно будет удалять сообщения от вашего потребителя (обработчика), вместо этого они просто поступят в handleMessage для обработки.Если вы хотите выполнить обработку в «основном» потоке, тогда вы просто создаете новый обработчик, если вы хотите выполнять обработку в фоновом режиме, чтобы избежать ANR, вы, вероятно, захотите использовать HandlerThread .Вот пример обработчика, работающего в своем собственном фоновом потоке:

HandlerThread handlerThread = new HandlerThread("Consumer");
handlerThread.start();
Handler consumer = new Handler(handlerThread.getLooper()) {
    public void handleMessage (Message msg) {
    }
};

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

...