Android: Когда следует использовать Handler() и когда следует использовать Thread?

Когда мне нужно что-то запустить асинхронно, например долго работающая задача или логика, использующая сеть, или по какой-либо причине, Запуск новой темы и ее запуск отлично работают. Создание Handler и его запуск также работают. Какая разница? Когда следует использовать каждый из них? В чем преимущества/причины использования Handler, а не Thread?

PS. - По этому вопросу, пусть игнорирует AsyncTask. - Handler().postDelayed случай использования ясен, для этого вопроса позвольте предположить, что мне нужна задача, чтобы начать немедленно.

Ответ 1

Если все, что вы делаете, "тяжело", вы должны делать это в потоке. Если вы явно не запускаете его в своем собственном потоке, он будет запускаться в основном потоке (UI), который может быть заметен как неудобный или медленный для ответа интерфейс ваших пользователей.

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

Типичное взаимодействие Thread/Handler может выглядеть примерно так:

Handler h = new Handler(){
    @Override
    public void handleMessage(Message msg){
        if(msg.what == 0){
            updateUI();
        }else{
            showErrorDialog();
        }
    }
};

Thread t = new Thread() {
    @Override
    public void run(){
        doSomeWork();
        if(succeed){
            //we can't update the UI from here so we'll signal our handler and it will do it for us.
            h.sendEmptyMessage(0);
        }else{
            h.sendEmptyMessage(1);
        }
    }   
};

В общем, примите домой, что вы должны использовать Thread каждый раз, когда выполняете какую-то работу, которая может быть долгой или очень интенсивной (т.е. что-либо в сети, файл IO, тяжелый арифметический и т.д.).

Ответ 2

Обработчик и поток - это действительно две разные вещи.

Необходимо создать поток для выполнения длительных заданий.

Обработчик - очень удобный объект для связи между двумя потоками (например: фоновый поток должен обновлять пользовательский интерфейс. Вы можете использовать обработчик для переноса некоторого Runnable из вашего фонового потока в поток пользовательского интерфейса).

Таким образом, у вас нет выбора между Handler или Thread. Используйте поток, чтобы выполнять тяжелые задания! (вы можете использовать обработчик, если ваш фоновый поток вызовет некоторое задание в другом потоке - большую часть времени поток пользовательского интерфейса)

Ответ 3

Handler и Thread - две разные вещи, но они не противоречат друг другу. Вы можете иметь Handler и Thread одновременно, и фактически каждый Handler должен работать в Thread.

Для получения дополнительной информации вы можете проверить эту статью.

введите описание изображения здесь

Ответ 4

A Handler работает на одном и том же Thread, a Thread работает в другом потоке.

Используйте обработчик, если вам нужно запустить что-то в том же потоке, обычно это элемент GUI или что-то в этом роде.

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

Ответ 5

Обработчики - лучший способ связи между фоном и потоком пользовательского интерфейса. Обычно обработчики связаны с сообщением "Очередь потока", и они используются для отправки сообщений и выполнения для сообщения.

Использование:

Тема: Выполнение задач в потоке saperate (Background), чем поток пользовательского интерфейса. (помогает разблокировать поток пользовательского интерфейса)

Обработчик Используется для связи между пользовательским интерфейсом и фоновым потоком.

Посмотрите на статью

Ответ 6

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

Вы можете использовать класс android.os.Handler или класс AsyncTasks для это.

Класс Handler может обновлять пользовательский интерфейс. Обработчик обеспечивает методы для приема экземпляров класса Message или Runnable.

Вы можете отправлять сообщения через метод sendMessage (Message msg) или с помощью метода sendEmptyMessage().

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

Ответ 7

В чем преимущества/причины использования Handler, а не Thread?

A Handler позволяет отправлять и обрабатывать сообщения и Runnable объекты, связанные с потоком MessageQueue. Каждый экземпляр Handler связан с одним потоком и этой очереди сообщений потока.

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

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

  • Чтобы запланировать сообщения и Runnables, которые будут выполняться как некоторая точка в будущем
  • Заблокировать действие, выполняемое в другом потоке, чем ваше собственное.

Если вы используете java-потоки, вам приходится обрабатывать somethings самостоятельно - синхронизация с основным потоком, отмена потока и т.д.

Этот единственный поток не создает пул потоков, если вы не используете API ThreadPoolExecutor или ExecutorService.

(Получил этот запрос из ваших комментариев на ответ Блэкбелта)

Почему бы не использовать Исполнителя? и даже если бы я хотел использовать обработчик для этого, как?

Ссылка: Статья эффективности потока

Существуют определенные виды работы, которые могут быть сведены к высокопараллельным распределенным задачам. При большом объеме рабочих пакетов это создает AsyncTask и HandlerThread подходящие классы. Однопоточный характер AsyncTask превратит всю работу с потоком в линейную систему. С другой стороны, с помощью класса HandlerThread требуется, чтобы программист вручную управлял балансировкой нагрузки между группой потоков.

ThreadPoolExecutor - вспомогательный класс, облегчающий этот процесс. Этот класс управляет созданием группы потоков, устанавливает их приоритеты и управляет распределением работы между этими потоками. По мере того, как рабочая нагрузка увеличивается или уменьшается, класс закручивает или уничтожает больше потоков, чтобы приспособиться к рабочей нагрузке.

 BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
 ThreadPoolExecutor executor = new ThreadPoolExecutor(
            Runtime.getRuntime().availableProcessors(),       // Initial pool size
            Runtime.getRuntime().availableProcessors(),       // Max pool size
            1, // KEEP_ALIVE_TIME
            TimeUnit.SECONDS, //  KEEP_ALIVE_TIME_UNIT
            workQueue);

Более подробную информацию вы можете найти в этой статье руководства по create-threadpool.

Взгляните на это сообщение для использования Handler для запуска нескольких экземпляров Runnable. В этом случае все задачи Runnable будут выполняться в одном потоке.

Android: тост в потоке

Ответ 8

Handler может использоваться совместно с Thread, чтобы создать механизм Queued. Uou может использовать Handler, чтобы опубликовать что-то на Thread Looper