Каковы отношения между Looper, Handler и MessageQueue в Android?



Я проверил официальную документацию Android / руководство для Looper,Handler и MessageQueue . Но я не мог этого понять. Я новичок в android, и очень запутался с этими понятиями.

990   5  

5 ответов:

A Looper это цикл обработки сообщений: он читает и обрабатывает элементы из MessageQueue. Элемент Looper класс обычно используется в сочетании с HandlerThread (подкласс Thread).

A Handler - это служебный класс, который облегчает взаимодействие с Looper-в основном путем размещения сообщений и Runnable объекты для потока MessageQueue. Когда Handler создается, привязывается к конкретному Looper (и связанный поток и очередь сообщений).

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

основного потока (а.к.а. Потоке пользовательского интерфейса) в Android-приложение устанавливается как поток обработчика перед созданием экземпляра приложения.

помимо документов класса, есть хорошее обсуждение всего этого здесь.

широко известно, что это незаконно обновление компонентов пользовательского интерфейса непосредственно из потоков, отличных от основной поток в android. Это android документ (обработка дорогостоящих операций в потоке пользовательского интерфейса) предлагает шаги, чтобы следовать, если нам нужно начать отдельный поток, чтобы сделать некоторые дорогая работа и обновить пользовательский интерфейс после его завершения. Идея состоит в том, чтобы создать проводник объект, связанный с основной поток, и после Runnable к нему в подходящее время. Это Runnable будет вызван на основной поток. Этот механизм реализован с помощью Looper и проводник классы.

The Looper класс поддерживает a MessageQueue, который содержит список сообщения. Важным характером Looper является то, что это связан С нить внутри которой Looper is создано. Эта ассоциация сохранить навсегда и не может быть сломан или изменен. Также обратите внимание, что поток не может быть связано с более чем один Looper. Чтобы гарантировать эту ассоциацию,Looper хранится в локальном хранилище потоков, и он не может быть создан непосредственно через его конструктор. Единственный способ создать его-это вызвать готовить статический метод на Looper. подготовьте метод сначала исследует ThreadLocal из текущего потока чтобы убедиться, что с потоком еще не связан петлитель. После осмотра, новый Looper создается и сохраняется в ThreadLocal. Подготовив Looper, мы можем назвать цикл метод на нем, чтобы проверить наличие новых сообщений и есть Handler бороться с ними.

как следует из названия,Handler класс в основном отвечает за обработку (добавление, удаление, отправку) сообщений текущего потока MessageQueue. А Handler экземпляр также привязан к a нитка. Элемент привязка между обработчиком и потоком достигается через Looper и MessageQueue. А Handler и всегда a Looper, а затем привязан к поток, связанный С Looper. В отличие от Looper, несколько экземпляров обработчика могут быть привязаны к одному потоку. Всякий раз, когда мы называем post или любые методы, похожие на Handler новое сообщение добавляется в связанный MessageQueue. В поле сообщения имеет значение ток Handler экземпляра. Когда Looper получил это сообщение, он вызывает dispatchMessage в поле назначения сообщения, чтобы сообщение возвращалось к экземпляру обработчика для обработки, но в правильном потоке. Отношения между Looper,Handler и MessageQueue показано ниже:

enter image description here

давайте начнем с петлителя. Вы можете понять отношения между Looper, обработчиком и MessageQueue более легко, когда вы понимаете, что такое Looper. Также вы можете лучше понять, что такое Looper в контексте GUI framework. Петлитель сделан, чтобы сделать 2 вещи.

1) Looper преобразует обычный поток, который заканчивается, когда его run() возвращает метод, в то, что работает непрерывно, пока приложение для Android не работает, который необходимо в GUI framework (технически, он все еще завершается, когда run() возвращает метод. Но позвольте мне пояснить, что я имею в виду, ниже).

2) Looper обеспечивает очереди где есть работа предстоит сделать, - это очередь, которая также необходима в рамках графического интерфейса.

как вы знаете, когда приложение запускается, система создает поток выполнения для приложения, называемого "main", а приложения Android обычно работают полностью в одном потоке по умолчанию "main нить." Но основной поток-это не какой-то секрет, специальный поток. Это просто обычный поток, который вы также можете создать с помощью new Thread() код, который означает, что он заканчивается, когда его run() возвращает метод! Подумайте о приведенном ниже примере.

public class HelloRunnable implements Runnable {
    public void run() {
        System.out.println("Hello from a thread!");
    }

    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
}

теперь давайте применим этот простой принцип к Android-приложению. Что произойдет, если приложение для Android будет работать в обычном потоке? Поток под названием "main" или " UI " или что-то еще запускает приложение и рисует весь пользовательский интерфейс. Итак, первый экран отображается на пользователи. Ну и что теперь? Основной поток заканчивается? Нет, это не должно ждать, пока пользователи что-то сделают, верно? Но как мы можем добиться такого поведения? Ну, мы можем попробовать с Object.wait() или Thread.sleep(). Например, основной поток завершает свою начальную работу для отображения первого экрана и спит. Он просыпается, что означает прерывается, когда новая работа, чтобы сделать принес. Пока все хорошо, но на данный момент нам нужна структура данных в виде очереди для хранения нескольких заданий. Подумайте о случае, когда пользователь касается экрана серийно, и задача занимает больше времени, чтобы закончить. Таким образом, нам нужна структура данных для хранения заданий, которые будут выполняться первым в первом порядке. Кроме того, вы можете себе представить, что реализация когда-либо выполняемого и обрабатываемого потока с использованием прерывания не так проста и приводит к сложному и часто недостижимому коду. Мы бы предпочли создать новый механизм для этой цели, и вот что такое Looper все о. Элемент официальный документ класса Looper говорит, "Темы по умолчанию не имеет цикла обработки сообщений, связанных с ними", и "Петля времени" класс "используется для запуска цикла обработки сообщений для потока". Теперь вы можете понять, что это значит.

давайте перейдем к обработчику и MessageQueue. Во-первых, MessageQueue-это очередь, о которой я упоминал выше. Он находится внутри петлителя, и это все. Вы можете проверить это с помощью исходный код класса Looper. Класс Looper имеет переменную-член MessageQueue.

тогда, что такое обработчик? Если есть очередь, тогда должен быть метод, который должен позволить нам поставить в очередь новую задачу, верно? Вот что делает Хэндлер. Мы можем поставить новую задачу в очередь (MessageQueue) с помощью различных post(Runnable r) методы. Вот и все. Это все о Петлителе, обработчике и MessageQueue.

мое последнее слово, так что в основном Looper-это класс, который создан для решения проблемы, которая возникает в GUI framework. Но такого рода потребности могут возникать и в других ситуациях. На самом деле это это довольно известный шаблон для многопоточного приложения, и вы можете узнать больше об этом в "параллельном программировании на Java" Дуга Леа(особенно, глава 4.1.4 "рабочие потоки" была бы полезна). Кроме того, вы можете себе представить, что этот механизм не уникален в Android framework, но все GUI-фреймворки могут нуждаться в чем-то подобном этому. Вы можете найти почти такой же механизм в Java Swing framework.

MessageQueue: это низкоуровневый класс, содержащий список сообщений, которые будут отправлены Looper. Сообщения не добавляются непосредственно в MessageQueue, а через Handler объекты, связанные с Looper.[3]

Looper: Он проходит по MessageQueue который содержит сообщения, которые будут отправлены. Фактическая задача управления очередью выполняется с помощью Handler который отвечает за обработку (добавление, удаление, отправка) сообщений в сообщении очередь.[2]

Handler: Это позволяет отправлять и обрабатывать Message и Runnable объекты, связанные с потока MessageQueue. Каждый экземпляр обработчика связан с одним потоком и очередью сообщений этого потока.[4]

при создании нового Handler, он привязан к потоку / очереди сообщений потока, который его создает - с этого момента,он будет доставлять сообщения и runnables к этому сообщению очередь и выполнить их, как они выходят из очереди сообщений.

пожалуйста, пройдите через изображение ниже[2] для лучшего понимания.

enter image description here

MessageQueue, Handler, Looper in Android MessageQueue:

MessageQueue-это цикл сообщений или очередь сообщений, которая в основном содержит список сообщений или исполняемых файлов (набор исполняемого кода).

другими словами MessageQueue-это очередь, которая имеет задачи, называемые сообщениями, которые должны быть обработаны.

Примечание: Android поддерживает MessageQueue на главном нитка.

Looper:

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

любой поток может иметь только один уникальный петлитель, это ограничение достигается с помощью концепции ThreadLocal хранения.

преимущества петлителя и MessageQueue

есть некоторые преимущества для использования петлителя и MessageQueue как описано ниже-

· при использовании MessageQueue выполнение является последовательным, поэтому в случае параллельных потоков это позволит избежать условий гонки.

· обычно поток не может быть повторно использован после завершения его работы. Но поток с Looper сохраняется до тех пор, пока вы не вызовете метод quit, поэтому вам не нужно создавать новый экземпляр каждый раз, когда вы хотите запустить задание в фоновом режиме.

обработчик:

обработчик позволяет общаться обратно с UI поток из другого фонового потока. Это полезно в android, поскольку android не позволяет другим потокам напрямую взаимодействовать с потоком пользовательского интерфейса.

обработчик позволяет отправлять и обрабатывать сообщения и запускаемые объекты, связанные с MessageQueue потока. Каждый экземпляр обработчика связан с одним потоком и очередью сообщений этого потока.

когда вы создаете новый обработчик, он привязан к нити очереди сообщений потока, который его создает - от укажите дальше, он будет доставлять сообщения и запускаемые файлы в эту очередь сообщений и выполнять их, когда они выходят из очереди сообщений.

есть два основных использования для обработчика:

(1) для планирования сообщений и runnables, которые будут выполняться в какой-то момент в будущем. Другими словами, выполните действие на том же потоке в будущем.

(2) Поставить в очередь действие, которое будет выполняться в другом потоке, чем ваш собственный. Другими словами помещать действие на разных нитка.

Comments

    Ничего не найдено.