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

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

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


person Daniel    schedule 23.05.2012    source источник


Ответы (6)


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

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

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

person oznus    schedule 12.10.2013

Обычный способ использования 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, это своего рода удобный способ.

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

person Richard    schedule 17.09.2013
comment
Это официальные документы. Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called. Я сэкономил ваше время. - person Asif Mushtaq; 01.07.2017

если я не использую HandlerThread (передаю его Looper в Handler), означает ли это, что в этом случае Handler использует Looper MainThread (поток пользовательского интерфейса)?

Ознакомьтесь с документацией по Handler.

Handler ()

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

Если ваш текущий поток — MainThread, он использует цикл MainThread (поток пользовательского интерфейса).

Чтобы явно связать Handler с вашим MainThread (потоком пользовательского интерфейса), напишите ниже код.

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

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

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

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

Вы можете найти пример кода @ Как исправить android.os. Исключение NetworkOnMainThreadException?

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

Если вы отправляете много событий в MainThread Looper, они будут выполняться в самом MainThread (UI Thread). Если отправленные задачи требуют больше времени для выполнения, MainThread будет заблокирован.

Ознакомьтесь с постом ниже, чтобы узнать о внутреннем устройстве Looper:

Какова цель Looper и как им пользоваться?

person Ravindra babu    schedule 11.02.2017

Как говорится в Doc:

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

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

person ρяσѕρєя K    schedule 23.05.2012

Вроде бы все объясняют, что он делает и как используется, но забыли объяснить, что этот поток нужно очищать после использования разработчиком, иначе он дает утечки. После использования вы должны позвонить

thread.quit()

выйти без обработки сообщения в очереди или

thread.quitSafely();

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

person The_Martian    schedule 26.11.2019

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

person prak253    schedule 07.06.2016