Я новичок в Android. Я хочу знать, что делает класс Looper, а также как его использовать. Я прочитал Android документацию класса Looper, но я не могу это полностью понять.
Я видел это во многих местах, но не мог понять его цели. Может ли кто-нибудь помочь мне, определив цель Looper, а также, если возможно, простой пример?
Какова цель Лупера и как его использовать?
Ответ 1
Что такое Looper?
Looper - это класс, который используется для выполнения сообщений (Runnables) в очереди. Обычные нити не имеют такой очереди, например. простой поток не имеет очереди. Он выполняется один раз и после завершения выполнения метода, поток не запускает другое сообщение (Runnable).
Где мы можем использовать класс Looper?
Если кто-то хочет выполнить несколько сообщений (Runnables), тогда он должен использовать класс Looper, который отвечает за создание очереди в потоке. Например, при написании приложения, которое загружает файлы из Интернета, мы можем использовать класс Looper для загрузки файлов в очередь.
Как это работает?
Существует метод prepare() для подготовки Looper. Затем вы можете использовать метод loop() для создания цикла сообщений в текущем потоке, и теперь ваш Looper готов выполнить запросы в очереди до тех пор, пока вы не выйдете из цикла.
Вот код, по которому вы можете подготовить Looper.
class LooperThread extends Thread {
      public Handler mHandler;
      @Override
      public void run() {
          Looper.prepare();
          mHandler = new Handler() {
              @Override
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };
          Looper.loop();
      }
  }
Ответ 2
Вы можете лучше понять, что такое Looper в контексте инфраструктуры GUI. Looper сделан, чтобы сделать 2 вещи.
1) Looper преобразует обычный поток, который завершается при возврате его метода run(), во что-то, работающее непрерывно до тех пор, пока не будет запущено приложение Android, что необходимо в графическом интерфейсе (Технически, он все еще завершается, когда возвращается метод run(). Но позвольте мне уточнить, что я имею в виду ниже).
2) Looper предоставляет очередь, в которой выполняются задания, которые также необходимы в среде GUI.
 Как вы, возможно, знаете, когда приложение запускается, система создает поток выполнения для приложения, называемый "основным", и приложения 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" или чем-то еще, запускает ваше приложение и рисует весь 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.
Ответ 3
Looper позволяет выполнять задачи последовательно в одном потоке. И обработчик определяет те задачи, которые нам нужно выполнить. Это типичный сценарий, который я пытаюсь проиллюстрировать в этом примере:
class SampleLooper extends Thread {
@Override
public void run() {
  try {
    // preparing a looper on current thread     
    // the current thread is being detected implicitly
    Looper.prepare();
    // now, the handler will automatically bind to the
    // Looper that is attached to the current thread
    // You don't need to specify the Looper explicitly
    handler = new Handler();
    // After the following line the thread will start
    // running the message loop and will not normally
    // exit the loop unless a problem happens or you
    // quit() the looper (see below)
    Looper.loop();
  } catch (Throwable t) {
    Log.e(TAG, "halted due to an error", t);
  } 
}
}
Теперь мы можем использовать обработчик в некоторых других потоках (например, поток ui), чтобы выполнить задачу на Looper для выполнения.
handler.post(new Runnable()
{
public void run() {
//This will be executed on thread using Looper.
    }
});
В потоке пользовательского интерфейса мы имеем неявный Looper, который позволяет обрабатывать сообщения в потоке ui.
Ответ 4
 Android Looper обертка прикрепить MessageQueue к Thread и управляет обработкой очереди. Это выглядит очень загадочно в документации Android, и часто мы можем столкнуться с проблемами доступа к пользовательскому интерфейсу Looper. Если мы не понимаем основ, с этим становится очень трудно справиться.
 Вот статья, которая объясняет жизненный цикл Looper, как его использовать и как использовать Looper в Handler
Looper = Thread + MessageQueue
Ответ 5
Определение Looper & Handler:
Looper - это класс, который превращает поток в поток конвейера, а обработчик предоставляет вам механизм для вставки задач в него из любых других потоков.
Подробности:
Таким образом, поток PipeLine - это поток, который может принимать больше задач из других потоков через обработчик.
Looper назван так, потому что он реализует цикл - берет следующую задачу, выполняет ее, затем берет следующую и так далее. Обработчик называется обработчиком, потому что он используется для обработки или принятия следующей задачи каждый раз из любого другого потока и передачи в Looper (Thread или PipeLine Thread).
Пример:
Отличным примером Looper and Handler или PipeLine Thread является загрузка нескольких изображений или загрузка их на сервер (Http) по одному в одном потоке вместо запуска нового потока для каждого сетевого вызова в фоновом режиме.
Узнайте больше здесь о Looper и Handler и определении Threading Thread:
Ответ 6
A Looper имеет synchronized MessageQueue, который использовался для обработки сообщений, помещенных в очередь.
Он реализует специальный шаблон хранения Thread.
Только один Looper за Thread. Ключевыми методами являются prepare(), loop() и quit().
 prepare() инициализирует текущий Thread как Looper. prepare() - это метод static, который использует класс ThreadLocal, как показано ниже.
   public static void prepare(){
       ...
       sThreadLocal.set
       (new Looper());
   }
-  prepare()должен быть вызван явно перед запуском цикла событий.
-  loop()запускает цикл событий, который ожидает, что сообщения поступят в конкретный поток сообщений Thread. После получения следующего сообщения методloop()отправляет сообщение его целевому обработчику
-  quit()отключает цикл событий. Он не завершает цикл, но вместо этого он вставляет специальное сообщение
 Looper можно запрограммировать в Thread с помощью нескольких шагов
-  Расширить Thread
-  Вызвать Looper.prepare()для инициализации Thread как aLooper
-  Создайте один или несколько Handler(s) для обработки входящих сообщений
-  Вызов Looper.loop()для обработки сообщений до тех пор, пока цикл не будет переданquit().
Ответ 7
Продолжительность жизни java Thread завершена после завершения метода run(). Одну нить нельзя запустить снова.
 Looper преобразует нормальный Thread в цикл сообщения. Ключевыми методами Looper являются:
void prepare ()
Инициализировать текущий поток в качестве петлителя. Это дает вам возможность создавать обработчики, которые затем ссылаются на этот петлитель, прежде чем начать цикл. Обязательно вызовите loop() после вызова этого метода и завершите его, вызвав quit().
void loop ()
Запустите очередь сообщений в этом потоке. Обязательно вызовите quit(), чтобы закончить цикл.
void quit()
Выход из петлителя.
Заставляет метод loop() завершаться без обработки каких-либо сообщений в очереди сообщений.
Эта статья статьи о мыслях от Janishar объясняет основные понятия красивым способом.
 Looper связан с потоком. Если вам нужно Looper в потоке пользовательского интерфейса, Looper.getMainLooper() вернет связанный поток.
Вам нужно Looper связать с Handler.
 Looper, Handler, а HandlerThread - метод андроидов для решения задач асинхронного программирования.
Как только у вас есть Handler, вы можете вызвать API ниже.
post (Runnable r)
Заставляет Runnable r добавляться в очередь сообщений. Runnable будет запущен в потоке, к которому прикреплен этот обработчик.
boolean sendMessage (Message msg)
Отбрасывает сообщение в конец очереди сообщений после всех ожидающих сообщений до текущего времени. Он будет получен в handleMessage (Message) в потоке, прикрепленном к этому обработчику.
HandlerThread - это удобный класс для запуска нового потока с петлевым механизмом. Затем петлитель можно использовать для создания классов обработчиков
В некоторых сценариях вы не можете запускать задачи Runnable в потоке пользовательского интерфейса.
например Сетевые операции: отправить сообщение в сокет, открыть URL-адрес и получить контент, прочитав InputStream
В этих случаях полезно использовать HandlerThread. Вы можете получить объект Looper из HandlerThread и создать Handler на HandlerThread вместо основного потока.
HandlerThread будет выглядеть следующим образом:
@Override
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}
См. ниже сообщение, например, код:
Ответ 8
Этот ответ не имеет никакого отношения к вопросу, но использование петлителя и способ создания человеком обработчика и петлителя во ВСЕХ ответах здесь - это плохая практика (некоторые объяснения верны, хотя), я должен опубликовать это:
HandlerThread thread = new HandlerThread(threadName);
thread.start();
Looper looper = thread.getLooper();
Handler myHandler = new Handler(looper);
и для полная реализация
Ответ 9
Обработка нескольких элементов вниз или загрузки в Service является лучшим примером.
 Handler и AsnycTask часто используются для распространения событий/сообщений между пользовательским интерфейсом (thread) и рабочим потоком или с задержкой действий. Поэтому они больше связаны с пользовательским интерфейсом.
A Looper обрабатывает задачи (Runnables, Futures) в связанной с потоком очереди в фоновом режиме - даже без взаимодействия пользователя или с отображаемым интерфейсом (приложение загружает файл в фоновом режиме во время разговора).
Ответ 10
Что такое Лупер?
ОТ ДОКУМЕНТОВ
 Looper Class используется для запуска цикла сообщений для thread. По умолчанию потоки не имеют циклы сообщений, связанной с ними; чтобы создать его, вызовите prepare() в потоке, который должен запустить цикл, а затем loop() чтобы он обрабатывал сообщения до тех пор, пока цикл не будет остановлен.
-  Looper- это цикл обработки сообщений:
- Важным символом Looper является то, что он связан с потоком, в котором создается Looper
-  Класс Looper поддерживает  MessageQueue, который содержит список сообщений. Важным символом Looper является то, что он связан с потоком, в котором создается Looper.
-  Looperназван так, потому что он реализует цикл - берет следующую задачу, выполняет ее, затем берет следующую и так далее.Handlerназывается обработчиком, потому что кто-то не может придумать лучшего имени
-  Android Looper- это класс Java в пользовательском интерфейсе Android, который вместе с классом Handler обрабатывает события пользовательского интерфейса, такие как нажатия кнопок, перерисовка экрана и переключение ориентации.
Как это устроено?
Создание Looper
  MessageQueue получает Looper и  MessageQueue, вызывая Looper.prepare() после своего запуска. Looper.prepare() идентифицирует вызывающий поток, создает объект Looper и MessageQueue и связывает поток
ОБРАЗЕЦ КОДА
class MyLooperThread extends Thread {
      public Handler mHandler; 
      public void run() { 
          // preparing a looper on current thread  
          Looper.prepare();
          mHandler = new Handler() { 
              public void handleMessage(Message msg) { 
                 // process incoming messages here
                 // this will run in non-ui/background thread
              } 
          }; 
          Looper.loop();
      } 
  }
Для получения дополнительной информации проверьте ниже пост



