Вы можете лучше понять, что такое Looper в контексте инфраструктуры GUI. Looper сделан, чтобы сделать 2 вещи.
1) Looper преобразует обычный поток , который завершается при возврате метода run (), во что-то непрерывное, пока не запустится приложение Android , что необходимо в среде графического интерфейса пользователя (Технически, он все еще завершается при возврате метода run (). Но позвольте мне уточнить, что я имею в виду ниже).
2) Looper предоставляет очередь которой выполняются задания, которые также необходимы в среде GUI.
Как вы, возможно, знаете, когда приложение запускается, система создает поток выполнения для приложения, называемый «основным», и приложения Android обычно работают полностью в одном потоке, по умолчанию «основной поток». Но главная тема не какая-то секретная, специальная тема . Это просто нормальный поток, похожий на потоки, которые вы создаете с помощью 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" или чем-то еще, запускает ваше приложение и рисует весь UI. Итак, первый экран отображается для пользователей. И что теперь? Основной поток заканчивается? Нет, не должно. Следует подождать, пока пользователи что-то сделают, верно? Но как мы можем достичь этого поведения? Ну, мы можем попробовать сObject.wait()
илиThread.sleep()
, Например, основной поток завершает свою начальную работу для отображения первого экрана и спит. Он пробуждается, что означает прерванный, когда выбирается новая работа. Пока все хорошо, но в данный момент нам нужна структура данных в виде очереди для хранения нескольких заданий. Подумайте о случае, когда пользователь касается экрана последовательно, и выполнение задачи занимает больше времени. Таким образом, нам нужна структура данных для хранения заданий, выполняемых в порядке «первым пришел - первым вышел». Кроме того, вы можете себе представить, что реализовать постоянно работающий поток и процесс-задание-при поступлении с использованием прерывания непросто, и это приводит к сложному и часто не поддерживаемому коду. Мы предпочли бы создать новый механизм для этой цели, и это то, что Лупер это все . Официальный документ класса Looperговорит: «По умолчанию потоки не имеют связанной с ними петли сообщений», а Looper - это класс, «используемый для запуска петли сообщений для потока». Теперь вы можете понять, что это значит.
Чтобы сделать вещи более понятными, давайте проверим код, в котором преобразован основной поток. Все это происходит в классе ActivityThread . В его методе main () вы можете найти приведенный ниже код, который превращает обычный основной поток в то, что нам нужно.
public final class ActivityThread {
...
public static void main(String[] args) {
...
Looper.prepareMainLooper();
Looper.loop();
...
}
}
и Looper.loop()
метод зацикливается бесконечно и удаляет сообщение из очереди и обрабатывает по одному:
public static void loop() {
...
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
...
msg.target.dispatchMessage(msg);
...
}
}
Итак, в основном Looper - это класс, созданный для решения проблемы, возникающей в среде GUI. Но такого рода потребности могут возникнуть и в другой ситуации. На самом деле это довольно известный шаблон для многопоточного приложения, и вы можете узнать о нем больше в « Параллельном программировании на Java » Дуга Ли (особенно было бы полезно, глава 4.1.4 «Рабочие потоки»). Кроме того, вы можете себе представить, что этот тип механизма не уникален в платформе Android, но все графические интерфейсы могут нуждаться в чем-то похожем на это. Вы можете найти почти такой же механизм в Java Swing Framework.