Я получил немного смущен о различиях между Handlers
, AsyncTask
иThreads
в Android. Я прочитал немало блогов и вопросов здесь, в StackOverflow.
Handler
являются фоновыми потоками, которые предоставляют вам возможность общаться с пользовательским интерфейсом. Например, обновление индикатора выполнения должно выполняться через Handler
. Используя обработчики, у вас есть преимущество MessagingQueues
, так что если вы хотите запланировать сообщения или обновить несколько элементов пользовательского интерфейса или иметь повторяющиеся задачи.
AsyncTask
они похожи, фактически они используют Handler
, но не работают в потоке пользовательского интерфейса, так что это хорошо для извлечения данных, например для извлечения веб-сервисов. Позже вы можете взаимодействовать с пользовательским интерфейсом.
Thread
однако не может взаимодействовать с пользовательским интерфейсом, обеспечить более «базовую» многопоточность, и вы пропустите все абстракции AsyncTask
.
Тем не менее, я хотел бы, чтобы соединение с сокетом работало. Должно ли это быть выполнено в обработчике или потоке, или дажеAsyncTask
? Взаимодействие с интерфейсом вообще не нужно. Имеет ли это значение с точки зрения производительности, которую я использую?
Между тем, документация была значительно улучшена.
Handler
не является потоком, и он ничего не выполняет. Это всего лишь средство для безопасной передачи сообщений из одного потока в очередь сообщений другого потока . Таким образом, обычно (по крайней мере) еще два потока должны быть созданы, которые затем могут использовать обработчик, но обработчик не может ничего выполнить сам.Ответы:
Как говорится в Руководстве по фоновой обработке Android с помощью Handlers, AsyncTask и Loaders на сайте Vogella:
Handler
Класс может быть использован для регистрации в тему и обеспечивает простой канал для передачи данных на эту тему.AsyncTask
Класс инкапсулирует создание фонового процесса и синхронизацию с основным потоком. Он также поддерживает отчеты о ходе выполнения задач.А в
Thread
основном является основным элементом многопоточности, который разработчик может использовать со следующим недостатком:А что касается
AsyncTask
, как сказано в «Справочнике разработчика Android» :Обновление май 2015: я нашел отличную серию лекций на эту тему.
Важное замечание : Если вы находитесь в точке, где вы планируете использовать
AsyncTask
решение своих проблем с потоками, вам следует сначала проверить,ReactiveX/RxAndroid
возможно, более подходящий шаблон программирования. Очень хороший ресурс для получения обзора - изучение RxJava 2 для Android на примере .источник
Если мы посмотрим на исходный код, мы увидим
AsyncTask
иHandler
написаны исключительно на Java. (Однако есть некоторые исключения. Но это не важный момент)Так что нет волшебства в
AsyncTask
илиHandler
. Эти занятия делают нашу жизнь проще как разработчик.Например: если программа A вызывает метод A (), метод A () может выполняться в другом потоке с программой A. Мы можем легко проверить это с помощью следующего кода:
Почему мы должны использовать новый поток для некоторых задач? Вы можете Google для этого. Много много причин, например: тяжелый подъем, длительные работы.
Итак, каковы различия между
Thread
,AsyncTask
иHandler
?AsyncTask
иHandler
написаны на Java (внутренне они используют aThread
), так что все, что мы можем сделать с помощьюHandler
илиAsyncTask
мы можем достичь с помощьюThread
тоже.Что может
Handler
иAsyncTask
действительно поможет?Наиболее очевидная причина - связь между потоком вызывающего и рабочим потоком. ( Поток вызывающего : поток, который вызывает рабочий поток для выполнения некоторых задач. Поток вызывающего не обязательно должен быть потоком пользовательского интерфейса). Конечно, мы можем общаться между двумя потоками другими способами, но есть много недостатков (и опасностей) из-за безопасности потоков.
Вот почему мы должны использовать
Handler
иAsyncTask
. Эти классы выполняют большую часть работы за нас, нам нужно только знать, какие методы переопределить.Разница между
Handler
иAsyncTask
заключается в следующем: используйте,AsyncTask
когда поток вызывающего является потоком пользовательского интерфейса . Вот что говорится в документе Android:Я хочу подчеркнуть два момента:
1) Простое использование потока пользовательского интерфейса (так, используйте, когда поток вызывающего является потоком пользовательского интерфейса).
2) Нет необходимости манипулировать обработчиками. (означает: вы можете использовать Handler вместо AsyncTask, но AsyncTask - более простой вариант).
В этом посте есть много вещей, которые я еще не сказал, например: что такое поток пользовательского интерфейса или почему это проще. Вы должны знать некоторые методы каждого класса и использовать его, вы полностью поймете причину.
@: когда вы прочитаете документ Android, вы увидите:
Поначалу это описание может показаться странным. Нам нужно только понять, что у каждого потока есть каждая очередь сообщений (например, список дел), и поток будет принимать каждое сообщение и делать это до тех пор, пока очередь сообщений не станет пустой (точно так же, как мы закончим нашу работу и отправимся спать). Так когда
Handler
общается, он просто отправляет сообщение вызывающему потоку и ожидает обработки.Сложно? Просто помните, что
Handler
можете безопасно общаться с вызывающим потоком.источник
После тщательного изучения, это прямо вперед.
AsyncTask
:Это простой способ использовать поток, ничего не зная о модели потока Java .
AsyncTask
дает различные обратные вызовы, соответствующие рабочему потоку и основному потоку.Используйте для небольших операций ожидания, таких как следующие:
Handler
:Когда мы устанавливаем приложение в Android, оно создает поток для этого приложения с именем MAIN UI Thread. Все действия выполняются в этой ветке. По правилу однопоточной модели android мы не можем получить доступ к элементам пользовательского интерфейса (растровое изображение, текстовое представление и т. Д.) Напрямую для другого потока, определенного внутри этого действия.
Обработчик позволяет вам общаться с потоком пользовательского интерфейса из других фоновых потоков. Это полезно в Android, так как Android не позволяет другим потокам напрямую взаимодействовать с потоком пользовательского интерфейса. Обработчик может отправлять и обрабатывать объекты Message и Runnable, связанные с MessageQueue потока. Каждый экземпляр обработчика связан с одним потоком и очередью сообщений этого потока. Когда создается новый обработчик, он привязывается к потоку / очереди сообщений потока, который его создает.
Это лучше всего подходит для:
Thread
:Теперь пришло время поговорить о теме.
Нить является родителем обоих
AsyncTask
иHandler
. Они оба используют потоки внутри себя, что означает, что вы также можете создать свою собственную модель потока, какAsyncTask
иHandler
, но это требует хорошего знания многопоточной реализации Java .источник
An
AsyncTask
используется для выполнения некоторых фоновых вычислений и публикации результатов в потоке пользовательского интерфейса (с дополнительными обновлениями прогресса). Поскольку вы не связаны с пользовательским интерфейсом, тогдаHandler
илиThread
кажется более подходящим.Вы можете икру фона
Thread
и передавать сообщения обратно в основной поток с помощьюHandler
«spost
метода.источник
Нить
Android поддерживает стандартные потоки Java . Вы можете использовать стандартные потоки и инструменты из пакета «
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
источник
Thread
:Вы можете использовать новый
Thread
для длительных фоновых задач, не влияя на поток пользовательского интерфейса. В ветке Java вы не можете обновить ветку пользовательского интерфейса.С нормальным потоком не очень полезен для архитектуры Android, были введены вспомогательные классы для потоков.
Вы можете найти ответы на свои вопросы на странице документации по производительности Threading .
Обработчик :
A
Handler
позволяет отправлять и обрабатывать сообщения иRunnable
объекты, связанные с потокомMessageQueue
. КаждыйHandler
экземпляр связан с одним потоком и очередью сообщений этого потока.Существует два основных варианта использования
Handler
:Составить график сообщений и исполняемых файлов, которые будут выполнены как определенный момент в будущем;
Поставить в очередь действие, которое будет выполнено в другом потоке, чем ваш собственный.
AsyncTask :
AsyncTask
позволяет правильно и легко использовать поток пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.Недостатки:
По умолчанию приложение помещает все
AsyncTask
объекты, которые оно создает, в один поток. Поэтому они выполняются последовательно и, как и в случае основного потока, особенно длинный рабочий пакет может блокировать очередь. По этой причине используйте AsyncTask для обработки рабочих элементов длительностью менее 5 мс .AsyncTask
Объекты также являются наиболее распространенными нарушителями для неявных ссылок.AsyncTask
объекты представляют риски, связанные с явными ссылками, а также.HandlerThread :
Вам может понадобиться более традиционный подход к выполнению блока работы в долго работающем потоке (в отличие от AsyncTask, который должен использоваться для рабочей нагрузки 5 мс ), и некоторая возможность управлять этим рабочим процессом вручную. Поток-обработчик, по сути, является долго выполняющимся потоком, который захватывает работу из очереди и обрабатывает ее.
ThreadPoolExecutor :
Этот класс управляет созданием группы потоков, устанавливает их приоритеты и управляет распределением работы между этими потоками. По мере увеличения или уменьшения рабочей нагрузки класс раскручивается или уничтожает больше потоков, чтобы приспособиться к рабочей нагрузке.
Если рабочей нагрузки больше, а одного
HandlerThread
недостаточно, вы можете пойти наThreadPoolExecutor
Поскольку взаимодействие с пользовательским интерфейсом не требуется, вы не можете пойти на
AsyncTask
. Обычные темы не очень полезны и, следовательно,HandlerThread
являются лучшим вариантом. Поскольку вы должны поддерживать сокетное соединение, обработчик в главном потоке вообще бесполезен. СоздайтеHandlerThread
и получитеHandler
от петлителяHandlerThread
.Если вы хотите связаться с потоком пользовательского интерфейса, вы можете использовать еще один обработчик для обработки ответа.
в свой
Runnable
, вы можете добавитьБолее подробную информацию о реализации можно найти здесь:
Android: тост в потоке
источник
На мой взгляд, потоки - не самый эффективный способ создания соединений с сокетами, но они обеспечивают большую функциональность с точки зрения запуска потоков. Я говорю это потому, что из-за опыта, длительный запуск потоков приводит к тому, что устройства становятся очень горячими и ресурсоемкими. Даже простой
while(true)
телефон будет нагревать в считанные минуты. Если вы говорите, что взаимодействие с пользовательским интерфейсом не важно, возможно, этоAsyncTask
хорошо, потому что они предназначены для долгосрочных процессов. Это всего лишь мое мнение по этому поводу.ОБНОВИТЬ
Пожалуйста, не обращайте внимания на мой ответ выше! Я ответил на этот вопрос еще в 2011 году, когда у меня было гораздо меньше опыта в Android, чем сейчас. Мой ответ выше вводит в заблуждение и считается неправильным. Я оставляю это там, потому что многие люди прокомментировали это ниже, исправляя меня, и я усвоил урок.
В этой ветке гораздо лучше других ответов, но я, по крайней мере, дам более правильный ответ. Нет ничего плохого в использовании обычной Java
Thread
; тем не менее, вы должны быть очень осторожны с реализацией этого, потому что неправильное выполнение может быть очень ресурсоемким (наиболее заметным симптомом может быть нагрев вашего устройства).AsyncTask
Они идеально подходят для большинства задач, которые вы хотите запускать в фоновом режиме (типичными примерами являются дисковый ввод-вывод, сетевые вызовы и вызовы базы данных). ОднакоAsyncTask
не следует использовать s для особо длительных процессов, которые могут потребоваться после того, как пользователь закрыл ваше приложение или перевел свое устройство в режим ожидания. Я бы сказал, что в большинстве случаев обо всем, что не принадлежит потоку пользовательского интерфейса, можно позаботиться вAsyncTask
.источник
AsyncTask
предназначен для выполнения операций в фоновом режиме не более нескольких секунд (не рекомендуется для загрузки файлов с сервера в мегабайтах или для выполнения ресурсоемких задач, таких как операции ввода-вывода файлов). Если вам нужно выполнить длительную операцию, вам настоятельно рекомендуется использовать нативные потоки Java. Java предоставляет вам различные связанные с потоками классы, чтобы делать то, что вам нужно. ИспользуйтеHandler
для обновления пользовательского интерфейса.источник
источник
Позвольте мне попытаться ответить на вопрос здесь на примере :) - MyImageSearch [Пожалуйста, обратитесь сюда к изображению основного экрана активности - содержащему текст редактирования / кнопку поиска / вид сетки]
Описание MyImageSearch - Как только пользователь введет данные в текстовое поле редактирования и нажмет на кнопку поиска, мы будем искать изображения в Интернете с помощью веб-сервисов, предоставляемых flickr (вам нужно только зарегистрироваться там, чтобы получить ключ / секретный токен) - для поиска мы отправляем запрос HTTP и получаем данные JSON обратно в ответ, содержащие URL-адреса отдельных изображений, которые мы затем будем использовать для загрузки вида сетки.
Моя реализация - в основном задании я определю внутренний класс, который расширяет AsyncTask для отправки HTTP-запроса в метод doInBackGround, извлекает ответ JSON и обновляет мой локальный ArrayList из FlickrItems, который я собираюсь использовать для обновления моего GridView через FlickrAdapter (расширяет BaseAdapter) и вызывает adapter.notifyDataSetChanged () в onPostExecute () AsyncTask для перезагрузки вида сетки. Обратите внимание, что здесь HTTP-запрос является блокирующим вызовом, из-за которого я сделал это через AsyncTask. И я могу кэшировать элементы в адаптере, чтобы увеличить производительность или сохранить их на SDCard. Сетка, которую я буду раздувать в FlickrAdapter, содержит в моей реализации индикатор выполнения и представление изображения. Ниже вы можете найти код для mainActivity, который я использовал.
Ответ на вопрос сейчас. Итак, когда у нас есть данные JSON для выборки отдельных изображений, мы можем реализовать логику получения изображений в фоновом режиме с помощью обработчиков, потоков или AsyncTask. Здесь следует отметить, что, поскольку мои загруженные изображения должны отображаться в пользовательском интерфейсе / главном потоке, мы не можем просто использовать потоки в том виде, как они есть, поскольку они не имеют доступа к контексту. В FlickrAdapter я мог придумать варианты:
Вот исходный код:
Я надеюсь, что мой ответ, хотя долго, поможет в понимании некоторых из более мелких деталей.
источник
Это зависит от того, какой из них выбрать, основываясь на требовании
Обработчик в основном используется для переключения из другого потока в основной поток, обработчик присоединяется к циклу, на котором он размещает свою выполняемую задачу в очереди. Так что, если вы уже находитесь в другом потоке и переключаетесь на основной поток, вам нужен дескриптор вместо асинхронной задачи или другого потока
Если обработчик, созданный не в главном потоке, который не является лупером, не выдаст ошибку, так как дескриптор создает нить, то этот поток должен быть сделан лоппером
AsyncTask используется для выполнения кода в течение нескольких секунд, который выполняется в фоновом потоке и передает его результат в основной поток ** * Ограничения AsyncTask 1. Асинхронная задача не привязана к жизненному циклу активности и продолжает выполняться, даже если ее активность уничтожена, тогда как загрузчик не выполняет. не имеют этого ограничения 2. Все асинхронные задачи имеют общий фоновый поток для выполнения, что также влияет на производительность приложения
Поток используется в приложении для фоновой работы, но он не имеет обратного вызова в основном потоке. Если требование удовлетворяет некоторым потокам, а не одному потоку и которым необходимо многократно выполнять задачу, то лучше использовать исполнитель пула потоков. Например, требование загрузки изображения из нескольких URL, таких как glide.
источник
Нить
Когда вы запускаете приложение, создается процесс для выполнения кода. Чтобы эффективно использовать вычислительный ресурс, потоки могут быть запущены внутри процесса, чтобы одновременно можно было выполнить несколько задач. Таким образом, потоки позволяют создавать эффективные приложения, эффективно используя процессор без простоев.
В Android все компоненты выполняются в одном основном потоке. Задачи очереди Android и выполняйте их одну за другой в главном потоке. Когда долго выполняющиеся задачи выполняются, приложение перестает отвечать на запросы.
Чтобы предотвратить это, вы можете создавать рабочие потоки и запускать фоновые или долго выполняющиеся задачи.
укротитель
Поскольку android использует однопоточную модель, компоненты пользовательского интерфейса создаются не поточно-безопасными. Это означает, что доступ к ним должен иметь только созданный им поток, то есть компонент пользовательского интерфейса должен обновляться только в основном потоке. Поскольку компонент пользовательского интерфейса выполняется в главном потоке, задачи, выполняемые в рабочих потоках, не могут изменять компоненты пользовательского интерфейса. Это где Handler входит в картину. Обработчик с помощью Looper может подключаться к новому потоку или существующему потоку и запускать код, который он содержит в подключенном потоке.
Обработчик делает возможным взаимодействие между потоками. Используя Handler, фоновый поток может отправлять результаты в него, а обработчик, подключенный к основному потоку, может обновлять компоненты пользовательского интерфейса в основном потоке.
AsyncTask
AsyncTask, предоставляемый android, использует как поток, так и обработчик для упрощения выполнения простых задач в фоновом режиме и обновления результатов из фонового потока в основной поток.
Пожалуйста, смотрите Android Thread, Handler, Asynctask и Пулы потоков для примеров.
источник
Handler
- это средство связи между потоками. В Android это в основном используется для связи с основным потоком путем создания и отправки сообщений через обработчикAsyncTask
- используется для выполнения долго работающих приложений в фоновом потоке. С помощью nAsyncTask
вы можете выполнить операцию в фоновом потоке и получить результат в основном потоке приложения.Thread
- это легкий процесс для достижения параллелизма и максимального использования процессора. В Android вы можете использовать поток для выполнения действий, которые не касаются пользовательского интерфейса приложенияисточник