Какова цель петлителя и как его использовать?
Я новичок в Android. Я хочу знать, что Looper
класс делает, а также как его использовать. Я прочитал Android Looper Class documentation но я не могу полностью понять его.
Я видел его во многих местах, но не могу понять его назначение. Может ли кто-нибудь помочь мне, определив цель Looper
, а также предоставляя простой пример, если это возможно?
9 ответов:
что такое Looper?
Looper-это класс, который используется для выполнения сообщений(Runnables) в очереди. Обычные потоки не имеют такой очереди, например, простой поток не имеет никакой очереди. Он выполняется один раз и после завершения выполнения метода, поток не будет запускать другое сообщение(Runnable).
где мы можем использовать класс Looper?
Если кто-то хочет выполнить несколько сообщений(Runnables), то он должен использовать класс Looper который отвечает за создание очереди в потоке. Например, при написании приложения, которое загружает файлы из интернета, мы можем использовать класс Looper, чтобы поместить файлы для загрузки в очередь.
как это работает?
здесь
prepare()
метод подготовки петлителя. Тогда вы можете использоватьloop()
метод для создания цикла сообщений в текущем потоке, и теперь ваш петлитель готов выполнять запросы в очереди, пока вы не выйдете петля.вот код, с помощью которого вы можете подготовить петлителя.
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 в контексте GUI framework. Петлитель сделан, чтобы сделать 2 вещи.
1) Looper преобразует обычный поток, который завершается, когда его метод run() возвращает, во что-то работать непрерывно, пока Android приложение не работает, который необходим в GUI framework (технически, он все еще завершается при возврате метода run (). Но позвольте мне уточнить, что я имею в виду ниже).
2) Looper предоставляет очередь где есть работа предстоит сделать, - это очередь, которая также необходима в рамках графического интерфейса.
как вы можете знать, когда приложение запускается, система создает поток выполнения для приложения, называемого "main", и приложения Android обычно работают полностью в одном потоке по умолчанию"main 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 class. В своем методе main () вы можете найти ниже код, который превращает обычный основной поток в то, что нам нужно.
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-это класс, который предназначен для решения проблемы, возникающей в GUI рамки. Но такого рода потребности могут возникать и в других ситуациях. На самом деле это довольно известный шаблон для нескольких потоков, и вы можете узнать больше об этом в "параллельное программирование на Java " Дуг Леа (особенно, глава 4.1.4 "рабочие потоки" было бы полезно). Кроме того, вы можете себе представить, что этот механизм не уникален в Android framework, но все рамки GUI могут нуждаться в чем-то подобном этому. Вы можете найти почти такой же механизм в Java Swing рамки.
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. } });
в потоке пользовательского интерфейса у нас есть неявный петлитель, который позволяет нам обрабатывать сообщения в потоке пользовательского интерфейса.
Android
Looper
это обертка для прикрепленияMessageQueue
toThread
и он управляет обработкой очереди. Это выглядит очень загадочно в документации Android и много раз мы можем столкнуться сLooper
связанные проблемы доступа к пользовательскому интерфейсу. Если мы не понимаем основы, это становится очень трудно справиться.здесь статьи что объясняет
Looper
жизненный цикл, как использовать его и использованиеLooper
наHandler
Looper = Thread + MessageQueue
Looper
- Это класс, который превращает поток в поток газопровод иHandler
дает вам механизм для того чтобы нажать задачи в его от всех других потоков.так
PipeLine Thread
это поток, который может принимать больше задач от других потоков черезHandler
.петлитель называется так, потому что он реализует цикл – берет следующую задачу, выполняет ее, затем берет следующую и так далее. Обработчик называется обработчиком, потому что он используется для обработки или принятия следующей задачи каждый время от любого другого потока и переход к Петлителю (поток или поток трубопровода).
очень идеальный пример петлителя и обработчика или конвейерного потока-загрузить более одного изображения или загрузить их на сервер (Http) по одному в одном потоке вместо запуска нового потока для каждого сетевого вызова в фоновом режиме.
подробнее здесь о Петлителе и обработчике и определении потока конвейера:
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()
запускает цикл событий, который ожидает поступления сообщений в messagequeue определенного потока. Как только будет получено следующее сообщение,loop()
метод отправляет сообщение своему целевому обработчикуquit()
завершает работу цикла событий. Он не завершает цикл, но вместо этого ставит в очередь специальное сообщение
Looper
можно запрограммировать вThread
через несколько действия
расширения
Thread
вызов
Looper.prepare()
для инициализации потока какLooper
создать один или несколько
Handler
(s) для обработки входящих сообщений- вызов
Looper.loop()
обрабатывать сообщения до тех пор, пока цикл не будет сообщенquit()
.
продолжительность жизни java Thread после окончания
run()
метод. Же поток не может быть запущен снова.Looper трансформирует нормальный
Thread
в цикл обработки сообщений. Ключевые методыLooper
являются :void prepare ()
инициализируйте текущий поток как петлитель. Это дает вам возможность создавать обработчики, которые затем ссылаются на этот петлитель, прежде чем фактически начать цикл. Обязательно вызовите loop () после вызова этого метод, и завершить его, вызвав quit ().
void loop ()
запустите очередь сообщений в этом потоке. Обязательно вызовите quit (), чтобы завершить цикл.
void quit()
выход из петлителя.
вызывает метод loop () для завершения без обработки каких-либо сообщений в очереди сообщений.
этой статьи mindorks Джанишар объясняет основные понятия в Ницце путь.
Looper
связан с потоком. Если вам нужноLooper
в потоке пользовательского интерфейса,Looper.getMainLooper()
вернется нити.вам нужно
Looper
связано с проводник.
Looper
,Handler
иHandlerThread
являются Android способ решения проблем асинхронного программирования.как только у вас есть
Handler
, вы можете позвонить ниже Апис.post (Runnable r)
вызывает Runnable R для добавления в очередь сообщений. Runnable будет выполняться в потоке, к которому присоединен этот обработчик.
boolean sendMessage (Message msg)
помещает сообщение в конец очереди сообщений после всех ожидающих сообщений до текущего времени. Он будет получен в handleMessage (сообщение), в потоке, прикрепленном к этому обработчику.
HandlerThread удобный класс для запуск нового потока, который имеет петлитель. Затем петлитель можно использовать для создания классов обработчиков
в некоторых случаях, вы не можете запустить
Runnable
задачи в потоке пользовательского интерфейса. например, сетевые операции: Отправить сообщение на сокете, открыть URL-адрес и получить содержимое, прочитавInputStream
в этих случаях
HandlerThread
полезно. Вы можете получитьLooper
объектHandlerThread
и создатьHandler
onHandlerThread
вместо основного потока.The HandlerThread код будет так:
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; }
см. ниже Сообщение, например код:
этот ответ не имеет ничего общего с вопросом, но использование looper и то, как люди создали обработчик и looper во всех ответах здесь-простая плохая практика (некоторые объяснения правильны), я должен опубликовать это:
HandlerThread thread = new HandlerThread(threadName); thread.start(); Looper looper = thread.getLooper(); Handler myHandler = new Handler(looper);
обработка нескольких вниз или загрузить элементы в сервис лучший пример.
Handler
иAsnycTask
часто используются для распространения События/Сообщения между UI (поток) и рабочий поток или отложить действия. Таким образом, они больше связаны с пользовательским интерфейсом.A
Looper
выполняет задачи (Runnables, Futures) в очереди, связанной с потоком, в фоновом режиме-даже без взаимодействия с пользователем или отображаемого пользовательского интерфейса (приложение загрузки файлов в фоновом режиме во время разговора).