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

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

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

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

Посмотрите документацию Handler

Handler ()

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

Если ваш текущий поток - MainThread, он использует MainThread (UI Thread) Looper.

Чтобы явно связать 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, выполняя операцию Network IO.

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

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

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

Отметьте ниже сообщение для внутренних компонентов Looper:

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

Ответ 5

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