Я новичок в Android. Я хочу знать, что Looper
делает класс, а также как его использовать. Я прочитал документацию по классу Android Looper, но не могу понять ее полностью. Я видел это во многих местах, но не мог понять его цель. Может ли кто-нибудь помочь мне, определив цель, Looper
а также приведя простой пример, если это возможно?
android
multithreading
android-looper
Хавар Раза
источник
источник
Ответы:
Что такое Лупер?
Looper - это класс, который используется для выполнения сообщений (Runnables) в очереди. Обычные потоки не имеют такой очереди, например, простой поток не имеет никакой очереди. Он выполняется один раз и после завершения выполнения метода поток не запускает другое сообщение (Runnable).
Где мы можем использовать класс Looper?
Если кто-то хочет выполнить несколько сообщений (Runnables), он должен использовать класс Looper, который отвечает за создание очереди в потоке. Например, при написании приложения, которое загружает файлы из Интернета, мы можем использовать класс Looper для помещения файлов для загрузки в очередь.
Как это работает?
Там есть
prepare()
способ приготовить лупер. Затем вы можете использоватьloop()
метод для создания цикла сообщений в текущем потоке, и теперь ваш Looper готов выполнять запросы в очереди, пока вы не выйдете из цикла.Вот код, по которому вы можете подготовить Looper.
источник
Вы можете лучше понять, что такое Looper в контексте инфраструктуры GUI. Looper сделан, чтобы сделать 2 вещи.
1) Looper преобразует обычный поток , который завершается при возврате метода run (), во что-то непрерывное, пока не запустится приложение Android , что необходимо в среде графического интерфейса пользователя (Технически, он все еще завершается при возврате метода run (). Но позвольте мне уточнить, что я имею в виду ниже).
2) Looper предоставляет очередь которой выполняются задания, которые также необходимы в среде GUI.
Как вы, возможно, знаете, когда приложение запускается, система создает поток выполнения для приложения, называемый «основным», и приложения Android обычно работают полностью в одном потоке, по умолчанию «основной поток». Но главная тема не какая-то секретная, специальная тема . Это просто нормальный поток, похожий на потоки, которые вы создаете с помощью
new Thread()
кода, что означает, что он завершается, когда возвращается его метод run ()! Подумайте о приведенном ниже примере.Теперь давайте применим этот простой принцип к приложениям для Android. Что произойдет, если приложение Android будет работать в обычном потоке? Поток с именем "main" или "UI" или чем-то еще, запускает ваше приложение и рисует весь UI. Итак, первый экран отображается для пользователей. И что теперь? Основной поток заканчивается? Нет, не должно. Следует подождать, пока пользователи что-то сделают, верно? Но как мы можем достичь этого поведения? Ну, мы можем попробовать с
Object.wait()
илиThread.sleep()
, Например, основной поток завершает свою начальную работу для отображения первого экрана и спит. Он пробуждается, что означает прерванный, когда выбирается новая работа. Пока все хорошо, но в данный момент нам нужна структура данных в виде очереди для хранения нескольких заданий. Подумайте о случае, когда пользователь касается экрана последовательно, и выполнение задачи занимает больше времени. Таким образом, нам нужна структура данных для хранения заданий, выполняемых в порядке «первым пришел - первым вышел». Кроме того, вы можете себе представить, что реализовать постоянно работающий поток и процесс-задание-при поступлении с использованием прерывания непросто, и это приводит к сложному и часто не поддерживаемому коду. Мы предпочли бы создать новый механизм для этой цели, и это то, что Лупер это все . Официальный документ класса Looperговорит: «По умолчанию потоки не имеют связанной с ними петли сообщений», а Looper - это класс, «используемый для запуска петли сообщений для потока». Теперь вы можете понять, что это значит.Чтобы сделать вещи более понятными, давайте проверим код, в котором преобразован основной поток. Все это происходит в классе ActivityThread . В его методе main () вы можете найти приведенный ниже код, который превращает обычный основной поток в то, что нам нужно.
и
Looper.loop()
метод зацикливается бесконечно и удаляет сообщение из очереди и обрабатывает по одному:Итак, в основном Looper - это класс, созданный для решения проблемы, возникающей в среде GUI. Но такого рода потребности могут возникнуть и в другой ситуации. На самом деле это довольно известный шаблон для многопоточного приложения, и вы можете узнать о нем больше в « Параллельном программировании на Java » Дуга Ли (особенно было бы полезно, глава 4.1.4 «Рабочие потоки»). Кроме того, вы можете себе представить, что этот тип механизма не уникален в платформе Android, но все графические интерфейсы могут нуждаться в чем-то похожем на это. Вы можете найти почти такой же механизм в Java Swing Framework.
источник
Looper позволяет последовательно выполнять задачи в одном потоке. И обработчик определяет те задачи, которые нам нужно выполнить. Это типичный сценарий, который я пытаюсь проиллюстрировать в этом примере:
Теперь мы можем использовать обработчик в некоторых других потоках (скажем, в потоке пользовательского интерфейса), чтобы опубликовать задачу в Looper для выполнения.
В потоке пользовательского интерфейса у нас есть неявный Looper, который позволяет нам обрабатывать сообщения в потоке пользовательского интерфейса.
источник
Android
Looper
- это оболочка для подключения,MessageQueue
котораяThread
управляет обработкой очереди. Это выглядит очень загадочно в документации Android, и часто мы можем столкнутьсяLooper
с проблемами доступа к пользовательскому интерфейсу. Если мы не понимаем основ, с этим становится очень трудно справиться.Вот статья, которая объясняет
Looper
жизненный цикл, как использовать его и использованиеLooper
вHandler
Looper = Thread + MessageQueue
источник
Определение Looper & Handler:
Looper - это класс, который превращает поток в поток конвейера, а обработчик дает вам механизм для вставки в него задач из любых других потоков.
Подробности:
Таким образом, поток PipeLine - это поток, который может принимать больше задач из других потоков через обработчик.
Looper назван так потому , что он реализует цикл - принимает следующую задачу, выполняет его, затем берет следующую и так далее. Обработчик называется обработчиком, потому что он используется для обработки или принятия следующей задачи каждый раз из любого другого потока и передачи в Looper (Thread или PipeLine Thread).
Пример:
Отличным примером Looper and Handler или PipeLine Thread является загрузка более одного изображения или загрузка их на сервер (Http) по одному в одном потоке вместо запуска нового потока для каждого сетевого вызова в фоновом режиме.
Узнайте больше здесь о Looper и Handler и определении Threading Thread:
Android Guts: Введение в Loopers и Обработчики
источник
У Looper есть функция
synchronized
MessageQueue
, используемая для обработки сообщений, помещенных в очередь.Он реализует
Thread
определенный шаблон хранения.Только один
Looper
заThread
. Основные методы включают в себяprepare()
,loop()
иquit()
.prepare()
инициализирует токThread
какLooper
.prepare()
этоstatic
метод, который используетThreadLocal
класс, как показано ниже.prepare()
должен быть вызван явно перед запуском цикла обработки событий.loop()
запускает цикл обработки событий, который ожидает поступления сообщений в очередь сообщений определенного потока. После получения следующего сообщенияloop()
метод отправляет сообщение своему целевому обработчику.quit()
выключает цикл событий. Это не завершает цикл, но вместо этого ставит в очередь специальное сообщениеLooper
может быть запрограммирован вThread
несколько этаповпростираться
Thread
Вызов
Looper.prepare()
для инициализации потока какLooper
Создать один или несколько
Handler
(ые) для обработки входящих сообщенийLooper.loop()
для обработки сообщений до тех пор, пока не будет передан циклquit()
.источник
Продолжительность жизни Java потока завершена после завершения
run()
метода. Та же тема не может быть запущена снова.Looper превращает нормальный
Thread
в цикл сообщений. Ключевые методыLooper
:В этой статье от Janishar мы подробно объясняем основные понятия.
Looper
связан с темой. Если вам нужноLooper
в потоке пользовательского интерфейса,Looper.getMainLooper()
вернет связанный поток.Вы должны
Looper
быть связаны с обработчиком .Looper
,Handler
ИHandlerThread
это способ Андроида решения проблем асинхронного программирования.После этого
Handler
вы можете позвонить ниже API.HandlerThread - удобный класс для запуска нового потока с петлителем. Цикл затем может быть использован для создания классов обработчиков
В некоторых случаях вы не можете запускать
Runnable
задачи в потоке пользовательского интерфейса. Например, сетевые операции: отправьте сообщение в сокет, откройте URL и получите контент, прочитавInputStream
В этих случаях
HandlerThread
полезно. Вы можете получитьLooper
объект изHandlerThread
и создатьHandler
наHandlerThread
вместо основного потока.Код HandlerThread будет выглядеть так:
Обратитесь к сообщению ниже для примера кода:
Android: тост в потоке
источник
Понимание нитей Looper
Поток Java - это единица выполнения, которая была разработана для выполнения задачи в своем методе run () и завершается после этого:
Но в Android есть много случаев, когда нам нужно поддерживать активность потока и ждать, например, пользовательских вводов / событий. Пользовательский интерфейс ака
Main Thread
.Основной поток в Android - это поток Java, который сначала запускается JVM при запуске приложения и продолжает работать до тех пор, пока пользователь не решит закрыть его или не встретит необработанное исключение.
Теперь обратите внимание на то, что хотя основной поток является потоком Java, он продолжает прослушивать пользовательские события и рисует кадры со скоростью 60 кадров в секунду на экране, но после каждого цикла он не умирает. как это так?
По умолчанию потоки не имеют связанного с ними цикла сообщений, но вы можете назначить его, вызвав Looper.prepare () в методе run, а затем вызвать Looper.loop ().
Если вы хотите глубже понять, как Looper управляет
Message
очередью объектов, вы можете взглянуть на исходный кодLooperclass
:Ниже приведен пример того, как вы можете создать
Looper Thread
и общаться сActivity
классом, используяLocalBroadcast
Использование :
Можем ли мы вместо этого использовать задачу Async или Intent Services?
Асинхронные задачи предназначены для выполнения коротких операций в фоновом режиме и обеспечения прогресса и результатов в потоке пользовательского интерфейса. Асинхронные задачи имеют ограничения, например, вы не можете создавать более 128 асинхронных задач и
ThreadPoolExecutor
разрешить только до 5 асинхронных задач .IntentServices
также предназначены для выполнения фоновых задач на более длительный срок, и вы можете использоватьLocalBroadcast
для общения сActivity
. Но сервисы разрушаются после выполнения задачи. Если вы хотите, чтобы он работал долго, вам нужно делать такие хакиwhile(true){...}
.Другие значимые варианты использования для Looper Thread:
Используется для двусторонней связи через сокет, когда сервер продолжает прослушивать сокет клиента и записывает подтверждение
Обработка растровых изображений в фоновом режиме. Передайте URL-адрес изображения в поток Looper, и он применит эффекты фильтра и сохранит его в определенном месте, а затем передаст временный путь изображения.
источник
Этот ответ не имеет ничего общего с вопросом, но использование «петлителя» и способа, которым люди создавали обработчик и петлитель во ВСЕХ ответах здесь, - просто плохая практика (хотя некоторые объяснения верны), я должен опубликовать это:
и для полной реализации
источник
Лучшим примером является обработка нескольких загруженных или загруженных элементов в Сервисе .
Handler
иAsnycTask
часто используются для распространения событий / сообщений между пользовательским интерфейсом (потоком) и рабочим потоком или для задержки действий. Таким образом, они больше связаны с пользовательским интерфейсом.A
Looper
обрабатывает задачи ( Runnables, Futures ) в очереди, связанной с потоками, в фоновом режиме - даже без взаимодействия с пользователем или отображаемого пользовательского интерфейса (приложение загружает файл в фоновом режиме во время вызова).источник
ОТ ДОКУМЕНТОВ
Looper
Looper
Класс, используемый для запуска цикла сообщений дляthread
. Потоки по умолчанию не имеют связанного с ними цикла сообщений; чтобы создать его, вызовитеprepare()
поток, который должен запустить цикл, а затемloop()
попросите его обрабатывать сообщения до тех пор, пока цикл не будет остановлен.Looper
- цикл обработки сообщений:MessageQueue
, который содержит список сообщений. Важным символом Looper является то, что он связан с потоком, в котором создается Looper.Looper
назван так, потому что он реализует цикл - берет следующую задачу, выполняет ее, затем берет следующую и так далее. ЭтоHandler
называется обработчиком, потому что кто-то не может придумать лучшего имениLooper
- это класс Java в пользовательском интерфейсе Android, который вместе с классом Handler обрабатывает события пользовательского интерфейса, такие как нажатия кнопок, перерисовка экрана и переключение ориентации.Поток получает
Looper
иMessageQueue
вызываяLooper.prepare()
после своего запуска.Looper.prepare()
идентифицирует вызывающий поток, создает лупер иMessageQueue
объект и связывает потокОБРАЗЕЦ КОДА
Для получения дополнительной информации проверьте ниже пост
источник