Вы можете лучше понять, что такое Looper в контексте инфраструктуры GUI.Looper предназначен для двух вещей:
1) Looper преобразует обычный поток , который завершается при возврате метода run (), во что-то непрерывное, пока приложение Android не будет запущено, который необходим в графическом интерфейсе (технически он все еще завершается при возврате метода run (). Но позвольте мне пояснить, что я имею в виду ниже).
2) Looper предоставляет очередь , где выполняемые задания ставятся в очередь, что также необходимо в графическом интерфейсе.
Как вы, возможно, знаете, когда приложение запускается, система создает поток выполнения для приложения, называемый «основным»Приложения 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();
...
}
}
и <a href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/Looper.java" rel="noreferrer">Looper.loop()</a>
бесконечно зацикливают цикл и удаляют сообщение и обрабатывают его по очереди.time:
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.