[android] Какова цель Лупера и как его использовать?



Answers

Вы можете лучше понять, что Looper находится в контексте графического интерфейса. Лупер должен сделать 2 вещи.

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

2) Looper предоставляет очередь, в которой выполняются задания, которые также требуются в графическом интерфейсе.

Как вы знаете, при запуске приложения система создает поток выполнения для приложения, называемый «основным», а приложения Android обычно запускаются целиком в одном потоке по умолчанию «основной поток». Но основная нить не является какой-то секретной, специальной нитью . Это обычный поток, похожий на потоки, созданные с помощью new Thread() кода 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 говорится: «Потоки по умолчанию не имеют связанного с ними цикла сообщений», а Looper - это класс, «используемый для запуска цикла сообщений для потока». Теперь вы можете понять, что это значит.

Чтобы сделать все более понятным, давайте проверим код, в котором преобразован основной поток. Все это происходит в классе ActivityThread . В своем основном () методе вы можете найти ниже код, который превращает обычный основной поток во что-то нужное.

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 - это класс, который предназначен для решения проблемы, которая возникает в графическом интерфейсе. Но такие потребности также могут произойти и в другой ситуации. На самом деле это довольно известный шаблон для многопоточного приложения, и вы можете узнать больше об этом в « Параллельном программировании на Java » Дуга Ли (особенно, глава 4.1.4 «Рабочие потоки» было бы полезно). Кроме того, вы можете себе представить, что этот механизм не уникален для Android-фреймворка, но все рамки GUI могут немного схожи с этим. Вы можете найти почти такой же механизм в Java Swing framework.

Question

Я новичок в Android. Я хочу знать, что делает класс Looper , а также как его использовать. Я прочитал документацию по классу Android Looper, но я не могу это полностью понять. Я видел это во многих местах, но не мог понять его цели. Может ли кто-нибудь помочь мне, определяя цель Looper а также, если возможно, простой пример?




Android Looper - это оболочка для присоединения MessageQueue к Thread и управление обработкой очереди. Это выглядит очень загадочно в документации для Android, и во многих случаях мы можем столкнуться с проблемами доступа к пользовательскому интерфейсу Looper . Если мы не понимаем основ, то очень сложно справиться.

Вот article которая объясняет жизненный цикл Looper , как его использовать и использование Looper in Handler

Looper = Thread + MessageQueue




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

Он реализует шаблон хранилища с конкретным потоком.

Только один Looper за Thread . К основным методам относятся prepare() , loop() и quit() .

prepare() инициализирует текущий поток как Looper . prepare() - static метод, который использует класс ThreadLocal как показано ниже.

   public static void prepare(){
       ...
       sThreadLocal.set
       (new Looper());
   }
  1. prepare() должен быть явно вызван перед запуском цикла событий.
  2. loop() запускает цикл событий, который ожидает, что Сообщения будут отправляться на конкретный поток сообщений Thread. После получения следующего сообщения метод loop() отправляет Message в его целевой обработчик
  3. quit() отключает цикл событий. Он не завершает цикл, но вместо этого он выдает специальное сообщение

Looper можно запрограммировать в Thread через несколько этапов

  1. Расширить Thread

  2. Вызовите Looper.prepare() чтобы инициализировать Thread как Looper

  3. Создайте один или несколько Handler для обработки входящих сообщений

  4. Вызовите Looper.loop() для обработки сообщений, пока цикл не будет Looper.loop() для quit() .



Лучший пример - обработка нескольких файлов вниз или загрузка в Service .

Handler и AsnycTask часто используются для распространения событий / сообщений между пользовательским интерфейсом (thread) и рабочим потоком или для задержки действий. Поэтому они больше связаны с пользовательским интерфейсом.

Looper обрабатывает задачи ( Runnables, Futures ) в связанной с потоком очереди в фоновом режиме - даже без взаимодействия с пользователем или с отображаемым интерфейсом (приложение загружает файл в фоновом режиме во время разговора).




Related