Intereting Posts
Изменить цвет фона Предпочтения Почему в моем Android ничего не отображается? Android WebView не обновляется после того, как содержимое веб-сайта было изменено с помощью JavaScript Длительная операция загрузки при открытии xml-макета на последнем ADT Что такое OBB (Opaque Binary Blob) на Android-сайте? Android – Как оживить переход активности при нажатии кнопки возврата по умолчанию Обрезание изображения снижает качество, а граница выглядит плохо Как сделать вспышку камеры вспышкой в ​​определенной последовательности? OnConfigurationChange не вызывается после изменения языка Ошибка идентификации устройства Android PopupMenu неправильно расположен внутри RecyclerView Как получить информацию об использовании аккумулятора Android по заявке Где находится предварительный просмотр макета Android Studio? Ошибка: Gradle: выполнение не выполнено для задачи ': app: crashlyticsCleanupResourcesDebug'. > Ошибка инструмента разработчика Crashlytics Android: установите фильтр серой шкалы в imageView

Зачем использовать HandlerThread в Android?

В android Handler можно использовать для отправки / обработки сообщения, если я не использую HandlerThread (передайте его Looper to Handler), означает ли это, что в этом случае Handler использует Looper MainThread (UI Thread)?

Какой результат получится, если Handler использует Looper MainThread? Может заблокировать mainThread?

Solutions Collecting From Web of "Зачем использовать HandlerThread в Android?"

Вы бы использовали HandlerThread в случае, если вы хотите выполнять фоновые задачи по одному, и вы хотите, чтобы эти задачи выполнялись в порядке выполнения.

Например, если вы хотите сделать несколько сетевых фоновых операций один за другим.

Да, у HandlerThread есть собственный петлитель, и обработчики могут быть созданы и отправлены, поэтому он не будет блокировать основной поток.

Как говорит Док :

Удобный класс для запуска нового потока, в котором есть петлитель.
Затем петлитель можно использовать для создания классов обработчиков.
Обратите внимание, что start () еще нужно вызвать.

Класс HanderThread наследуется от класса Thread, который инкапсулирует объект Looper, так что нам все равно, что Looper открывают и публикуют детали. Как и в случае нормального потока, мы должны использовать Looper.prepare() и Looper.loop() для преобразования его в LooperThread .

Обычный способ использования HandlerThread:

 HandlerThread thread = new HandlerThread("A Handler Thread"); thread.start(); Handler handler = new Handler(thread.getLooper()){ @Override public void handleMessage(Message msg) { //.... } }; 

Поскольку HandlerThread может создавать Looper для Handler, это своего рода удобный способ.

Когда вы создаете нового обработчика, он привязан к очереди потоков / сообщений потока, который его создает, – см. Официальные документы …

HandlerThread полезен, если вы хотите выполнить много фоновых задач, поскольку у него есть собственный петлитель. Обычно, если вы отправляете сообщение обработчику, он использует петлитель MainThread. Это означает, что задача выполняется в потоке пользовательского интерфейса. Но в случае HandlerThread эти задачи выполняются в рабочем потоке. Вы можете найти более подробное объяснение здесь

Из официальной документации Handler :

Экземпляр обработчика связан с одним потоком и очереди сообщений этого потока. Когда вы создаете нового обработчика , он привязан к очереди потоков / сообщений потока, который его создает – с этой точки он будет доставлять сообщения и runnables в очередь сообщений и выполнять их по мере их выхода из сообщения очередь.

Для обработчика используются два основных вида использования:

  1. Планировать сообщения и исполняемые файлы, которые должны выполняться как некоторые моменты в будущем
  2. Чтобы установить действие, которое должно выполняться в другом потоке, чем ваше собственное.

Когда процесс создается для вашего приложения, его основной поток предназначен для запуска очереди сообщений, которая занимается управлением объектами приложения верхнего уровня ( действия, широковещательные приемники и т. Д.) И любыми окнами, которые они создают. Вы можете создавать свои собственные потоки и общаться с основным потоком приложения через обработчик .

Это делается путем вызова тех же методов post или sendMessage что и раньше, но из вашего нового потока. Указанное Runnable или Message будет запланировано в очереди сообщений обработчика и обработано, когда это необходимо.

Если я не использую HandlerThread (передаю его Looper to Handler), означает ли это, что в этом случае Handler использует Loop MainThread (UI Thread)?

Если вы напишете его, как показано ниже, он использует основной поток.

 Handler mHandler = new Handler(Looper.getMainLooper(); 

Если вы пишете, как HandlerThread ниже, он использует HandlerThread

 HandlerThread handlerThread = new HandlerThread("HandlerThread"); handlerThread.start(); Handler requestHandler = new Handler(handlerThread.getLooper()); 

Если у вас есть какая-либо операция ввода-вывода в сети в задаче Runnable , вы не можете использовать петлитель основного потока. В этом случае HandlerThread удобен для отправки Runnable задачи, выполняющей операцию сетевого ввода-вывода.

Какой результат получится, если Handler использует Looper MainThread? Может заблокировать mainThread?

Если вы хотите, чтобы обработчик обрабатывал сообщения асинхронно, установите асинхронный параметр как истинный во время построения.

Вы можете проверить grepcode для реализации Handler

Реализация конструктора:

 /** * Use the {@link Looper} for the current thread * and set whether the handler should be asynchronous. * * Handlers are synchronous by default unless this constructor is used to make * one that is strictly asynchronous. * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. * * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. * * @hide */ public Handler(boolean async) { this(null, async); } public Handler(Looper looper, Callback callback, boolean async) { mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; }