Обработчик против AsyncTask против потока

Я немного запутался в различиях между Handlers, AsyncTask и Threads в Android. Я прочитал немало блогов и вопросов здесь, в StackOverflow.

Handler - это фоновые потоки, которые обеспечивают взаимодействие с пользовательским интерфейсом. Например, обновление индикатора выполнения должно выполняться через Handler. Используя обработчики, у вас есть преимущество MessagingQueues, поэтому, если вы хотите запланировать сообщения или обновить несколько элементов пользовательского интерфейса или иметь повторяющиеся задачи.

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

Thread однако не может взаимодействовать с пользовательским интерфейсом, обеспечивает более «базовую» многопоточность, и вы упускаете все абстракции AsyncTask.

Однако я хотел бы, чтобы соединение через сокет работало. Следует ли это запускать в обработчике, потоке или даже AsyncTask? Взаимодействие с пользовательским интерфейсом вообще не требуется. Есть ли разница в производительности, которую я использую?

Между тем, документация была значительно улучшена.


person Alx    schedule 06.08.2011    source источник


Ответы (12)


Как руководство по фоновой обработке Android с обработчиками, AsyncTask и загрузчиками на Сайт Vogella пишет:

Класс Handler может использоваться для регистрации в потоке и обеспечивает простой канал для отправки данных в этот поток.

Класс AsyncTask инкапсулирует создание фонового процесса и синхронизацию с основным потоком. Он также поддерживает отчеты о ходе выполнения запущенных задач.

А Thread - это, по сути, основной элемент многопоточности, который разработчик может использовать со следующим недостатком:

Если вы используете потоки Java, вы должны выполнить следующие требования в своем собственном коде:

  • Синхронизация с основным потоком, если вы отправляете результаты обратно в пользовательский интерфейс.
  • Нет по умолчанию для отмены цепочки
  • Нет пула потоков по умолчанию
  • Нет по умолчанию для обработки изменений конфигурации в Android

Что касается AsyncTask, как сказано в Справочнике разработчика Android:

AsyncTask обеспечивает правильное и простое использование потока пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.

AsyncTask разработан как вспомогательный класс для Thread и Handler и не представляет собой общую структуру потоковой передачи. В идеале AsyncTasks следует использовать для коротких операций (максимум несколько секунд). Если вам нужно поддерживать работу потоков в течение длительного времени, настоятельно рекомендуется использовать различные API-интерфейсы, предоставляемые пакетом java.util.concurrent, такие как Исполнитель, ThreadPoolExecutor и FutureTask.

Обновление, май 2015 г .: Я нашел отличную серию лекций по этой теме.

Это поиск в Google: Дуглас Шмидт читает лекцию по параллелизму и синхронизации Android

Это видео с первой лекции на YouTube.

Все это является частью курса CS 282 (2013): Системное программирование для Android от Университета Вандербильта. Вот плейлист YouTube.

Дуглас Шмидт кажется отличным лектором

Важно: если вы планируете использовать AsyncTask для решения проблем с потоками, вам следует сначала проверить _ 10_ для возможно более подходящего шаблона программирования. Очень хороший ресурс для получения обзора - Изучение RxJava 2 для Android на примере.

person Daniel F    schedule 15.04.2015
comment
В этой серии лекций эта ссылка приведет вас прямо к некоторым примерам цепочек: youtu.be/4Vue_KuXfCk?t= 19 мин. 24 сек. - person Aggressor; 21.08.2015

Если мы посмотрим на исходный код, мы увидим, что AsyncTask и Handler написаны исключительно на Java. (Хотя есть некоторые исключения. Но это не важно)

Итак, в AsyncTask или Handler нет магии. Эти классы облегчают нашу жизнь как разработчика.

Например: если программа A вызывает метод A (), метод A () может работать в другом потоке с программой A. Мы можем легко проверить, выполнив следующий код:

Thread t = Thread.currentThread();    
int id = t.getId();

Почему мы должны использовать новую ветку для некоторых задач? Вы можете найти это в Google. Много-много причин, например: подъем тяжестей, длительные работы.

Итак, в чем разница между Thread, AsyncTask и Handler?

AsyncTask и Handler написаны на Java (внутри они используют Thread), поэтому все, что мы можем делать с Handler или AsyncTask, мы можем достичь и с помощью Thread.

Что действительно может помочь Handler и AsyncTask?

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

Вот почему мы должны использовать Handler и AsyncTask. Эти классы делают за нас большую часть работы, нам нужно только знать, какие методы нужно переопределить.

Разница между Handler и AsyncTask заключается в следующем: используйте AsyncTask, когда поток вызывающего является потоком пользовательского интерфейса. Вот что говорится в документе Android:

AsyncTask обеспечивает правильное и простое использование потока пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.

Хочу выделить два момента:

1) Простое использование потока пользовательского интерфейса (так что используйте, когда поток вызывающего пользователя является потоком пользовательского интерфейса).

2) Нет необходимости манипулировать обработчиками. (означает: вы можете использовать Handler вместо AsyncTask, но AsyncTask - более простой вариант).

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

@: когда вы прочтете документ Android, вы увидите:

Обработчик позволяет отправлять и обрабатывать объекты Message и Runnable, связанные с MessageQueue потока.

Поначалу это описание может показаться странным. Нам нужно только понять, что в каждом потоке есть каждая очередь сообщений (например, список дел), и поток будет принимать каждое сообщение и делать это до тех пор, пока очередь сообщений не станет пустой (точно так же, как мы заканчиваем нашу работу и ложимся спать). Итак, когда Handler обменивается данными, он просто передает сообщение вызывающему потоку и ожидает обработки.

Сложный? Просто помните, что Handler может безопасно связываться с вызывающим потоком.

person hqt    schedule 21.03.2012
comment
фактически asynctask также основан на обработчике и futuretask, см. - person Sumit; 23.08.2016
comment
AsyncTask - это, по сути, вспомогательный класс, построенный на основе Handler и Thread. developer.android.com/reference/android/os/AsyncTask.html. Посмотрите на документ AsyncTask разработан как вспомогательный класс для Thread и Handler. AsyncTask выпущен в API3, а Handler существует с API1. - person hjchin; 09.11.2016

Если присмотреться ко всему, все будет прямо.

AsyncTask:

Это простой способ использовать поток, ничего не зная о модели потока Java. AsyncTask дает различные обратные вызовы, соответствующие рабочему потоку и основному потоку.

Используется для небольших операций ожидания, например следующих:

  1. Получение некоторых данных из веб-сервисов и отображение поверх макета.
  2. Запрос к базе данных.
  3. Когда вы поймете, что запущенная операция никогда не будет вложенной.

Handler:

Когда мы устанавливаем приложение в Android, оно создает для этого приложения поток под названием MAIN UI Thread. Все действия выполняются внутри этого потока. Согласно правилу однопоточной модели Android, мы не можем получить доступ к элементам пользовательского интерфейса (растровое изображение, текстовое представление и т. Д.) Напрямую для другого потока, определенного внутри этого действия.

Обработчик позволяет вам взаимодействовать с потоком пользовательского интерфейса из других фоновых потоков. Это полезно в Android, поскольку Android не позволяет другим потокам напрямую взаимодействовать с потоком пользовательского интерфейса. Обработчик может отправлять и обрабатывать объекты Message и Runnable, связанные с MessageQueue потока. Каждый экземпляр Handler связан с одним потоком и очередью сообщений этого потока. Когда создается новый обработчик, он привязывается к потоку / очереди сообщений потока, который его создает.

Лучше всего подходит для:

  1. Это позволяет вам создавать очереди сообщений.
  2. Расписание сообщений.

Thread:

Пришло время поговорить о ветке.

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

person Lavekush Agrawal    schedule 09.05.2014
comment
AsyncTask api фактически написан с использованием Futures, Handlers и Executors. См. Исходный код: grepcode.com/file_/repository.grepcode.com/java/ext/ - person IgorGanapolsky; 10.10.2016

AsyncTask используется для выполнения некоторых фоновых вычислений и публикации результата в потоке пользовательского интерфейса (с необязательными обновлениями хода выполнения). Поскольку пользовательский интерфейс вас не интересует, то Handler или Thread кажутся более подходящими.

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

person Eugene S    schedule 06.08.2011

Тема

Android поддерживает стандартные Java Threads. Вы можете использовать стандартные потоки и инструменты из пакета «java.util.concurrent», чтобы поместить действия в фоновый режим. Единственное ограничение заключается в том, что вы не можете напрямую обновлять пользовательский интерфейс из фонового процесса.

Если вам нужно обновить пользовательский интерфейс из фоновой задачи, вам необходимо использовать некоторые классы, специфичные для Android. Вы можете использовать для этого класс «android.os.Handler» или класс «AsyncTask».

Обработчик

Класс «Handler» может обновлять пользовательский интерфейс. Дескриптор предоставляет методы для получения сообщений и для исполняемых файлов. Чтобы использовать обработчик, вы должны создать его подкласс и переопределить handleMessage() для обработки сообщений. Для обработки Runable вы можете использовать метод post();. Вам нужен только один экземпляр обработчика в вашей деятельности.

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

AsyncTask

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

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

http://mobisys.in/blog/2012/01/android-threads-handlers-and-asynctask-tutorial/

http://www.slideshare.net/HoangNgoBuu/android-thread-handler-and-asynctask

person Harshal Benake    schedule 24.03.2014

Thread:

Вы можете использовать новый Thread для длительных фоновых задач, не влияя на поток пользовательского интерфейса. Из потока Java вы не можете обновить поток пользовательского интерфейса.

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

Вы можете найти ответы на свои вопросы на странице документации Threading performance.

Обработчик:

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

Есть два основных применения Handler:

  1. Чтобы запланировать выполнение сообщений и исполняемых файлов в какой-то момент в будущем;

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

AsyncTask:

AsyncTask обеспечивает правильное и простое использование потока пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.

Недостатки:

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

  2. AsyncTask объекты также являются наиболее частыми нарушителями при проблемах с неявными ссылками. AsyncTask объекты также представляют риски, связанные с явными ссылками.

HandlerThread:

Вам может потребоваться более традиционный подход к выполнению блока работы в длительном потоке (в отличие от AsyncTask, который следует использовать для рабочей нагрузки 5 мс) и некоторая возможность управлять этим рабочим процессом вручную. Поток-обработчик - это, по сути, длительный поток, который берет работу из очереди и работает с ней.

ThreadPoolExecutor:

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

Если рабочая нагрузка больше и одного HandlerThread недостаточно, вы можете выбрать ThreadPoolExecutor

Однако я хотел бы, чтобы соединение через сокет работало. Следует ли это запускать в обработчике, потоке или даже AsyncTask? Взаимодействие с пользовательским интерфейсом вообще не требуется. Есть ли разница в производительности, которую я использую?

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

 HandlerThread handlerThread = new HandlerThread("SocketOperation");
 handlerThread.start();
 Handler requestHandler = new Handler(handlerThread.getLooper());
 requestHandler.post(myRunnable); // where myRunnable is your Runnable object. 

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

final Handler responseHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            //txtView.setText((String) msg.obj);
            Toast.makeText(MainActivity.this,
                    "Foreground task is completed:"+(String)msg.obj,
                    Toast.LENGTH_LONG)
                    .show();
        }
    };

в вашем Runnable вы можете добавить

responseHandler.sendMessage(msg);

Более подробную информацию о реализации можно найти здесь:

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

person Ravindra babu    schedule 27.08.2017

На мой взгляд, потоки - не самый эффективный способ подключения к сокетам, но они предоставляют наибольшую функциональность с точки зрения запуска потоков. Я говорю это потому, что по опыту продолжительное выполнение потоков приводит к тому, что устройства сильно нагреваются и потребляют много ресурсов. Даже простой while(true) нагреет телефон за считанные минуты. Если вы говорите, что взаимодействие с пользовательским интерфейсом не важно, возможно, AsyncTask - это хорошо, потому что они предназначены для долгосрочных процессов. Это только мое мнение по этому поводу.

ОБНОВЛЕНИЕ

Не обращайте внимания на мой ответ выше! Я ответил на этот вопрос еще в 2011 году, когда у меня был гораздо меньше опыта работы с Android, чем сейчас. Мой ответ выше вводит в заблуждение и считается неправильным. Я оставляю это там, потому что многие люди прокомментировали это ниже, исправляя меня, и я усвоил свой урок.

В этой теме есть гораздо лучшие ответы, но я, по крайней мере, дам мне более правильный ответ. Нет ничего плохого в использовании обычного Java Thread; однако вам действительно следует быть осторожными с тем, как вы его реализуете, потому что неправильное выполнение может очень сильно нагружать процессор (наиболее заметным признаком может быть нагрев вашего устройства). AsyncTasks идеально подходят для большинства задач, которые вы хотите выполнять в фоновом режиме (распространенными примерами являются дисковый ввод-вывод, сетевые вызовы и вызовы базы данных). Однако AsyncTasks не следует использовать для особенно длительных процессов, которые могут потребоваться для продолжения после того, как пользователь закроет ваше приложение или переведет свое устройство в режим ожидания. Я бы сказал, что в большинстве случаев обо всем, что не принадлежит потоку пользовательского интерфейса, можно позаботиться в AsyncTask.

person Brian    schedule 06.08.2011
comment
спасибо, действительно ли есть причина, по которой я должен использовать Threads вместо AsyncTasks? Или это более рекомендуется использовать? - person Alx; 06.08.2011
comment
Кажется, вы сами частично разбираетесь в AsyncTasks. AsyncTasks особенно полезны для долгосрочных и ресурсоемких задач. Вы можете использовать поток, который я использовал в первом приложении, в котором использовались сокеты, но по опыту я обнаружил, что потоки очень интенсивны для процессора из-за объема работы, для выполнения которой они предназначены. Возможно, это неправильная причина, но AsyncTasks кажутся более оптимизированными для Android, чем простые потоки. - person Brian; 06.08.2011
comment
@AeroDroid В вашем примере: простое while (true), вы привяжете сюда процессор, если не добавите состояние сна в цикл. Это верно для любого бесконечного цикла. Если вы хотите уменьшить использование ЦП из-за этих накладных расходов, приостановите поток на несколько миллисекунд в конце цикла. - person Error 454; 07.09.2011
comment
@Error 454 - это интересно! Если бы вам нужно было выбрать подходящее время для сна, было бы оно от 40 до 80 миллисекунд? - person Abhijit; 10.11.2011
comment
@Abhijit Из игровых материалов, которые я сделал в SDL, простого добавления 10 мс сна в цикл было достаточно, чтобы упасть с 99% процессора до ~ 0 во время простоя. - person Error 454; 11.11.2011
comment
На самом деле developer.android.com/reference/android/os/AsyncTask.html говорит: AsyncTasks в идеале следует использовать для КОРОТКИХ операций. Вы также должны использовать их осторожно, так как они могут быть отклонены системой без выполнения! - person type-a1pha; 12.07.2013
comment
потоки - не самый эффективный способ подключения сокетов - да, это так. Всегда используйте блокировку ввода-вывода (без опроса!) В своем потоке, и вы сможете максимально эффективно использовать ресурсы. (Для дальнейшей оптимизации вы можете использовать каналы NIO для эффективной обработки нескольких соединений в одном потоке одновременно, но все же: вы должны использовать блокировку ввода-вывода.) - person JimmyB; 24.11.2015
comment
~ возможно, AsyncTask хорош, потому что они предназначены для долгосрочных процессов. Все наоборот! - person IgorGanapolsky; 10.10.2016
comment
@ type-a1pha это не против Asynctask. Я думаю, что это проблема потока, которая используется в Asynctask внутри. - person David; 07.11.2016

AsyncTask предназначен для выполнения операций не более нескольких секунд в фоновом режиме (не рекомендуется для мегабайт загрузки файлов с сервера или для задач с интенсивным вычислением ЦП, таких как операции ввода-вывода файлов). Если вам нужно выполнить длительную операцию, вам настоятельно рекомендуется использовать собственные потоки Java. Java предоставляет вам различные классы, связанные с потоками, чтобы делать то, что вам нужно. Используйте Handler для обновления потока пользовательского интерфейса.

person sky    schedule 24.03.2014

Позвольте мне попытаться ответить на этот вопрос на примере :) - MyImageSearch [Пожалуйста, отнесите сюда изображение основного экрана активности - содержащего текст редактирования / кнопку поиска / вид сетки]

MyImageSearch

Описание MyImageSearch - Как только пользователь вводит данные в текстовое поле редактирования и нажимает кнопку поиска, мы будем искать изображения в Интернете через веб-службы, предоставляемые flickr (вам нужно только зарегистрируйтесь там, чтобы получить ключ / секретный токен) - для поиска мы отправляем HTTP-запрос и получаем данные JSON в ответ, содержащие URL-адреса отдельных изображений, которые мы затем будем использовать для загрузки представления сетки.

Моя реализация - В основном действии я определю внутренний класс, который расширяет AsyncTask для отправки HTTP-запроса в методе doInBackGround, получения ответа JSON и обновления моего локального ArrayList для FlickrItems, которым я являюсь. собираюсь использовать для обновления моего GridView через FlickrAdapter (расширяет BaseAdapter) и вызывать адаптер .notifyDataSetChanged () в onPostExecute () AsyncTask, чтобы перезагрузить представление сетки. Обратите внимание, что здесь HTTP-запрос - это блокирующий вызов, из-за которого я сделал это через AsyncTask. И я могу кэшировать элементы в адаптере для повышения производительности или хранить их на SDCard. Сетка, которую я буду увеличивать в FlickrAdapter, в моей реализации содержит индикатор выполнения и представление изображений. Ниже вы можете найти код для mainActivity, который я использовал.

Ответьте на вопрос сейчас. Итак, как только у нас есть данные JSON для выборки отдельных изображений, мы можем реализовать логику получения изображений в фоновом режиме с помощью обработчиков, потоков или AsyncTask. Здесь следует отметить, что, поскольку мои изображения после загрузки должны отображаться в пользовательском интерфейсе / основном потоке, мы не можем просто использовать потоки как есть, поскольку у них нет доступа к контексту. В FlickrAdapter я мог придумать следующие варианты:

  • Вариант 1. Создайте LooperThread [расширяет поток] - и продолжайте загружать изображения последовательно в одном потоке, оставляя этот поток открытым [looper.loop ()]
  • Вариант 2: использовать пул потоков и опубликовать исполняемый файл через myHandler, который содержит ссылку на мой ImageView, но поскольку представления в представлении сетки повторно используются, снова может возникнуть проблема, когда изображение с индексом 4 отображается с индексом 9 [загрузка может займи больше времени]
  • Вариант 3 [я использовал это]: используйте пул потоков и отправьте сообщение в myHandler, которое содержит данные, связанные с индексом ImageView и самим ImageView, поэтому при выполнении handleMessage () мы будем обновлять ImageView только в случае совпадения currentIndex индекс изображения, которое мы пытались загрузить.
  • Выбор 4: использовать AsyncTask для загрузки изображений в фоновом режиме, но здесь у меня не будет доступа к количеству потоков, которое я хочу в пуле потоков, и оно зависит от версии Android, но в варианте 3 я могу принять осознанное решение. размера пула потоков в зависимости от используемой конфигурации устройства.

Вот исходный код:

public class MainActivity extends ActionBarActivity {

    GridView imageGridView;
    ArrayList<FlickrItem> items = new ArrayList<FlickrItem>();
    FlickrAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageGridView = (GridView) findViewById(R.id.gridView1);
        adapter = new FlickrAdapter(this, items);
        imageGridView.setAdapter(adapter);
    }

    // To avoid a memory leak on configuration change making it a inner class
    class FlickrDownloader extends AsyncTask<Void, Void, Void> {



        @Override
        protected Void doInBackground(Void... params) {
            FlickrGetter getter = new FlickrGetter();

            ArrayList<FlickrItem> newItems = getter.fetchItems();

            // clear the existing array
            items.clear();

            // add the new items to the array
            items.addAll(newItems);

            // is this correct ? - Wrong rebuilding the list view and should not be done in background
            //adapter.notifyDataSetChanged();

            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            adapter.notifyDataSetChanged();
        }

    }

    public void search(View view) {
        // get the flickr data
        FlickrDownloader downloader = new FlickrDownloader();
        downloader.execute();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

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

person akshaymani    schedule 24.08.2014
comment
Могу ли я узнать причину, по которой мое объяснение, основанное на примере для аналогии, было отвергнуто, чтобы я также извлек из этого урок? - person akshaymani; 27.08.2014
comment
Прежде всего, спасибо за ваш ответ, хотя эта тема немного устарела, основные концепции все еще актуальны. На мой первоначальный вопрос вообще нет ответа, вы приводите пример и объясняете, как это работает, но вопросы спрашивают о различиях между обработчиком, асинтаксической задачей и потоком. - person Alx; 21.09.2014
comment
@ 80leaves, хорошо, теперь я понял, я попытался объяснить, как я пришел к выводу, что предпочитаю один путь другому. В любом случае, хотелось бы услышать ваше / других мнение о том, правильно ли то, что я написал, или можно ли его улучшить. - person akshaymani; 27.09.2014

Это зависит от того, какой из них выбрать, зависит от требований

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

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

AsyncTask используется для выполнения кода в течение нескольких секунд, который выполняется в фоновом потоке и передает свой результат в основной поток. ** * Ограничения AsyncTask 1. Асинхронная задача не привязана к жизненному циклу активности, и он продолжает работать, даже если его активность уничтожена, тогда как у загрузчика нет этого ограничения 2. Все асинхронные задачи используют один и тот же фоновый поток для выполнения, что также влияет на производительность приложения

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

person mani    schedule 07.08.2019

Тема

Когда вы запускаете приложение, создается процесс для выполнения кода. Для эффективного использования вычислительных ресурсов в процессе можно запускать потоки, чтобы одновременно можно было выполнять несколько задач. Таким образом, потоки позволяют создавать эффективные приложения за счет эффективного использования процессора без простоев.

В Android все компоненты выполняются в единственном вызываемом основном потоке. Система Android ставит задачи в очередь и выполняет их одну за другой в основном потоке. Когда выполняются длительные задачи, приложение перестает отвечать.

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

Обработчик

Поскольку в Android используется однопоточная модель, компоненты пользовательского интерфейса создаются не потокобезопасными, что означает, что только созданный им поток должен получать к ним доступ, что означает, что компонент пользовательского интерфейса должен обновляться только в основном потоке. Поскольку компонент пользовательского интерфейса выполняется в основном потоке, задачи, выполняемые в рабочих потоках, не могут изменять компоненты пользовательского интерфейса. Здесь на сцену выходит Хэндлер. Обработчик с помощью Looper может подключиться к новому потоку или существующему потоку и запустить код, который он содержит, в подключенном потоке.

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

AsyncTask

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

Примеры см. В потоках Android, обработчиках, асинхронных задачах и пулах потоков.

person Arnav Rao    schedule 28.03.2018

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

AsyncTask - используется для выполнения длительно работающих приложений в фоновом потоке. С помощью nAsyncTask вы можете выполнять операцию в фоновом потоке и получать результат в основном потоке приложения.

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

person arjun    schedule 09.02.2017