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

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

Solutions Collecting From Web of "Какова цель Лупера и как его использовать?"

Что такое Лупер?

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(); } } 

Вы можете лучше понять, что 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() цикл цикла бесконечно и dequeue сообщение и обрабатывать по одному за раз:

 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-фреймворков, но для всех графических интерфейсов может потребоваться несколько схожий с этим. Вы можете найти почти такой же механизм в Java Swing framework.

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 thread), чтобы отправить задачу на Looper для выполнения.

 handler.post(new Runnable() { public void run() { //This will be executed on thread using Looper. } }); 

В потоке пользовательского интерфейса мы имеем неявный Looper, который позволяет нам обрабатывать сообщения в потоке ui.

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

Вот статья, которая объясняет жизненный цикл Лупера, как его использовать и использование Looper в Handler – http://prasanta-paul.blogspot.kr/2013/09/android-looper-and-toast-from.html Надеюсь, что это будет помогает.

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

Таким образом, PipeLine Thread – это поток, который может принимать больше задач из других потоков через Handler .

Looper назван так потому, что он реализует цикл – выполняет следующую задачу, выполняет ее, затем берет следующую и так далее. Обработчик называется обработчиком, потому что он используется для обработки или принятия этой следующей задачи каждый раз из любого другого потока и перехода к Looper (Thread или PipeLine Thread).

Идеальный пример Looper and Handler или PipeLine Thread – загрузить несколько изображений или загрузить их на сервер (Http) один за другим в одном потоке вместо того, чтобы запускать новый поток для каждого сетевого вызова в фоновом режиме.

Подробнее здесь о Looper and Handler и определении Pipeline Thread:

Android Guts: введение в Loopers и Handlers

Looper имеет синхронизированный MessageQueue, который используется для обработки сообщений, помещенных в очередь. Он реализует шаблон хранилища с конкретным потоком. Только один метод Looper / Thread Key включает команды prepare (), loop () и quit (). Prepare () инициализирует текущий поток как Looper. Подготовьте статический метод, который использует класс ThreadLocal, как показано ниже.

  public static void prepare(){ ... sThreadLocal.set (new Looper()); } 

Prepare () должен быть явно вызван перед запуском цикла событий.
Loop () запускает цикл событий, который ожидает, что сообщения поступят в конкретный поток сообщений Thread. После получения следующего сообщения метод loop () отправляет сообщение в обработчик целевого обработчика quit (), который завершает цикл события. Он не завершает цикл, но вместо этого он выдает специальное сообщение

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

 1) Extend Thread 2) Call Looper.prepare() to initialize Thread as a looper 3) Create one or more Handlers to process the incoming messages 4) Call Looper.loop() to process messages until the loop is told to quit. 

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

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

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