Обработчик против AsyncTask против потока
Я немного запутался по поводу различий между Handlers
, AsyncTask
а также Threads
в Android. Я прочитал довольно много блогов и вопросов здесь в stackru.
Handler
являются фоновыми потоками, которые предоставляют вам возможность общаться с пользовательским интерфейсом. Например, обновление индикатора выполнения должно быть выполнено через Handler
, Используя обработчики, вы получаете преимущество MessagingQueues
, так что если вы хотите запланировать сообщения или обновить несколько элементов пользовательского интерфейса или иметь повторяющиеся задачи.
AsyncTask
похожи, на самом деле они используют Handler
, но не запускается в потоке пользовательского интерфейса, поэтому он полезен для извлечения данных, например для извлечения веб-служб. Позже вы можете взаимодействовать с пользовательским интерфейсом.
Thread
однако не может взаимодействовать с пользовательским интерфейсом, обеспечить более "базовую" многопоточность, и вы пропустите все абстракции AsyncTask
,
Однако я бы хотел, чтобы в сервисе работало сокетное соединение. Должно ли это быть выполнено в обработчике или потоке, или даже в AsyncTask
? Взаимодействие с интерфейсом вообще не нужно. Имеет ли это значение с точки зрения производительности, которую я использую?
Между тем документация была значительно улучшена.
12 ответов
Как говорится в Руководстве по фоновой обработке Android с помощью Handlers, AsyncTask и Loaders на сайте Vogella:
Handler
Класс может использоваться для регистрации в потоке и обеспечивает простой канал для отправки данных в этот поток.
AsyncTask
Класс инкапсулирует создание фонового процесса и синхронизацию с основным потоком. Он также поддерживает отчеты о ходе выполнения задач.
ИThread
в основном это основной элемент многопоточности, который разработчик может использовать со следующим недостатком:
Если вы используете потоки Java, вы должны выполнить следующие требования в своем собственном коде:
- Синхронизация с основным потоком, если вы публикуете результаты обратно в пользовательский интерфейс
- Нет по умолчанию для отмены потока
- Нет пула потоков по умолчанию
- Нет по умолчанию для обработки изменений конфигурации в Android
И относительноAsyncTask
, как сказано в Справочнике разработчика Android:
AsyncTask
позволяет правильно и легко использовать поток пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.
AsyncTask
предназначен, чтобы быть вспомогательным классом вокругThread
а такжеHandler
и не является общей структурой потоков. AsyncTasks в идеале следует использовать для коротких операций (максимум несколько секунд). Если вам нужно, чтобы потоки работали в течение длительного периода времени, настоятельно рекомендуется использовать различные API, предоставляемые пакетом java.util.concurrent, такие как Executor, ThreadPoolExecutor и FutureTask.
Обновление май 2015: я нашелотличную серию лекций на эту тему.
Это Google Search: лекция Дугласа Шмидта android параллелизм и синхронизация
Это видео первой лекции на YouTube
Все это является частью CS 282 (2013): Системное программирование для Android от Университета Вандербильта. Вот плейлист YouTube
Дуглас Шмидт кажется отличным лектором
Важно: если вы находитесь в точке, где вы планируете использовать AsyncTask
чтобы решить ваши проблемы с потоками, вы должны сначалапроверитьReactiveX/RxAndroid
для возможно более подходящего шаблона программирования. Очень хорошим ресурсом для получения обзора является изучение RxJava 2 для Android на примере.
Если вы посмотрите на исходный код 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 - более простой вариант).
В этом посте есть много вещей, которые я еще не сказал, например: что такое поток пользовательского интерфейса или почему это проще. Вы должны знать какой-то метод для каждого вида и использовать его, вы полностью поймете, почему..
@: когда вы прочитаете документ Android, вы увидите:
Обработчик позволяет отправлять и обрабатывать объекты Message и Runnable, связанные с MessageQueue потока
Сначала они могут показаться странными. Просто поймите, что у каждого потока есть каждая очередь сообщений (например, список дел), и поток будет принимать каждое сообщение и делать это до тех пор, пока очередь сообщений не станет пустой (точно так же, как вы заканчиваете свою работу и ложитесь спать). Так когда Handler
связывается, просто выдает сообщение вызывающему потоку и ожидает обработки. Сложно? Просто запомни это Handler
может общаться с потоком вызывающего абонента безопасным способом.
После тщательного изучения, это прямо вперед.
AsyncTask
:
Это простой способ использовать поток, ничего не зная о модели потока Java.AsyncTask
дает различные обратные вызовы, соответствующие рабочему потоку и основному потоку.
Используйте для небольших операций ожидания, таких как следующие:
- Извлечение некоторых данных из веб-сервисов и отображение поверх макета.
- Запрос к базе данных.
- Когда вы поймете, что запущенная операция никогда не будет вложенной.
Handler
:
Когда мы устанавливаем приложение в Android, оно создает поток для этого приложения с именем MAIN UI Thread. Все действия выполняются в этой ветке. По правилу однопоточной модели android мы не можем получить доступ к элементам пользовательского интерфейса (растровое изображение, текстовое представление и т. Д.) Напрямую для другого потока, определенного внутри этого действия.
Обработчик позволяет вам общаться с потоком пользовательского интерфейса из другого фонового потока. Это полезно в Android, так как Android не позволяет другим потокам напрямую взаимодействовать с потоком пользовательского интерфейса. Обработчик может отправлять и обрабатывать объекты Message и Runnable, связанные с MessageQueue потока. Каждый экземпляр обработчика связан с одним потоком и очередью сообщений этого потока. Когда создается новый обработчик, он привязывается к потоку / очереди сообщений потока, который его создает.
Это лучше всего подходит для:
- Это позволяет вам делать очереди сообщений.
- Планирование сообщений.
Thread
:
Теперь пришло время поговорить о теме.
Нить является родителем обоих AsyncTask
а также Handler
, Они оба используют потоки внутри себя, что означает, что вы также можете создать свою собственную модель потока, такую как AsyncTask
а также Handler
, но это требует хорошего знания многопоточной реализации Java.
AsyncTask
используется для выполнения некоторых фоновых вычислений и публикации результатов в потоке пользовательского интерфейса (с дополнительными обновлениями прогресса). Так как вы не связаны с пользовательским интерфейсом, то Handler
или же Thread
кажется более подходящим.
Вы можете породить фон Thread
и передавать сообщения обратно в основной поток с помощью Handler
"s post
метод.
Android поддерживает стандартные потоки Java. Вы можете использовать стандартные темы и инструменты из пакета "java.util.concurrent
"Положить действия на задний план. Единственным ограничением является то, что вы не можете напрямую обновлять пользовательский интерфейс из фонового процесса.
Если вам нужно обновить пользовательский интерфейс из фоновой задачи, вам нужно использовать некоторые классы для Android. Вы можете использовать класс "android.os.Handler
Для этого или класса "AsyncTask
"
Класс "Handler
Может обновить пользовательский интерфейс. Дескриптор предоставляет методы для получения сообщений и для запуска. Чтобы использовать обработчик, вы должны создать его подкласс и переопределить handleMessage()
обрабатывать сообщения. Обрабатывать Runable
Вы можете использовать метод post();
Вам нужен только один экземпляр обработчика в вашей деятельности.
Вы в теме можете публиковать сообщения через метод sendMessage(Message msg)
или же sendEmptyMessage
,
Если у вас есть 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.
Handler
позволяет отправлять и обрабатывать сообщения и Runnable
объекты, связанные с потоком MessageQueue
, каждый Handler
Экземпляр связан с одним потоком и очередью сообщений этого потока.
Есть два основных использования Handler
:
Составить график сообщений и исполняемых файлов, которые будут выполнены как определенный момент в будущем;
Поставить в очередь действие, которое будет выполнено в другом потоке, чем ваш собственный.
AsyncTask
позволяет правильно и легко использовать поток пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.
Недостатки:
По умолчанию приложение выдвигает все
AsyncTask
объекты, которые он создает в один поток. Поэтому они выполняются последовательно, и, как и в случае основного потока, особенно длинный рабочий пакет может блокировать очередь. По этой причине используйте AsyncTask для обработки рабочих элементов длительностью менее 5 мс.AsyncTask
Объекты также являются наиболее распространенными нарушителями для неявных ссылок.AsyncTask
объекты представляют риски, связанные с явными ссылками, а также.
Вам может понадобиться более традиционный подход к выполнению блока работы в более длинном потоке (в отличие от AsyncTask, который должен использоваться для рабочей нагрузки 5 мс), и некоторая возможность управлять этим рабочим процессом вручную. Поток-обработчик, по сути, является долго выполняющимся потоком, который захватывает работу из очереди и обрабатывает ее.
Этот класс управляет созданием группы потоков, устанавливает их приоритеты и управляет распределением работы между этими потоками. Когда рабочая нагрузка увеличивается или уменьшается, класс раскручивается или уничтожает больше потоков, чтобы приспособиться к рабочей нагрузке.
Если рабочая нагрузка больше и больше HandlerThread
не достаточно, вы можете пойти на ThreadPoolExecutor
Однако я бы хотел, чтобы в сервисе работало сокетное соединение. Должно ли это выполняться в обработчике, потоке или даже в AsyncTask? Взаимодействие с интерфейсом вообще не нужно. Имеет ли это значение с точки зрения производительности, которую я использую?
Поскольку взаимодействие с пользовательским интерфейсом не требуется, вы не можете пойти на AsyncTask
, Нормальные темы не очень полезны и, следовательно, HandlerThread
это лучший вариант. Поскольку вы должны поддерживать сокетное соединение, обработчик в главном потоке вообще бесполезен. Создать 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);
Более подробную информацию о реализации можно найти здесь:
На мой взгляд, потоки - не самый эффективный способ создания соединений с сокетами, но они обеспечивают большую функциональность с точки зрения запуска потоков. Я говорю это потому, что из-за опыта, длительный запуск потоков приводит к тому, что устройства становятся очень горячими и ресурсоемкими. Даже простой while(true)
разогреет телефон за считанные минуты. Если вы говорите, что взаимодействие с пользовательским интерфейсом не важно, возможно, AsyncTask
это хорошо, потому что они предназначены для долгосрочных процессов. Это всего лишь мое мнение по этому поводу.
ОБНОВИТЬ
Пожалуйста, не обращайте внимания на мой ответ выше! Я ответил на этот вопрос еще в 2011 году, когда у меня было гораздо меньше опыта в Android, чем сейчас. Мой ответ выше вводит в заблуждение и считается неправильным. Я оставляю это там, потому что многие люди прокомментировали это ниже, исправляя меня, и я усвоил свой урок.
В этой ветке гораздо лучше других ответов, но я, по крайней мере, дам более правильный ответ. Нет ничего плохого в использовании обычной Java Thread
; тем не менее, вы должны быть очень осторожны с тем, как реализовать это, потому что неправильное выполнение может быть очень ресурсоемким (наиболее заметным симптомом может быть нагрев вашего устройства). AsyncTask
Они идеально подходят для большинства задач, которые вы хотите запускать в фоновом режиме (типичными примерами являются дисковый ввод-вывод, сетевые вызовы и вызовы базы данных). Тем не мение, AsyncTask
Не следует использовать его для особо длительных процессов, которые могут потребоваться после того, как пользователь закрыл ваше приложение или перевел свое устройство в режим ожидания. Я бы сказал, что в большинстве случаев обо всем, что не принадлежит потоку пользовательского интерфейса, можно позаботиться о AsyncTask
,
AsyncTask
предназначен для выполнения операций в фоновом режиме не более нескольких секунд (не рекомендуется для загрузки файлов с сервера в мегабайтах или для выполнения интенсивных вычислительных задач, таких как операции ввода-вывода файлов). Если вам нужно выполнить длительную операцию, вам настоятельно рекомендуется использовать нативные потоки Java. Java предоставляет вам различные связанные с потоками классы, чтобы делать то, что вам нужно. использование Handler
обновить поток пользовательского интерфейса.
public class RequestHandler {
public String sendPostRequest(String requestURL,
HashMap<String, String> postDataParams) {
URL url;
StringBuilder sb = new StringBuilder();
try {
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getPostDataString(postDataParams));
writer.flush();
writer.close();
os.close();
int responseCode = conn.getResponseCode();
if (responseCode == HttpsURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
sb = new StringBuilder();
String response;
while ((response = br.readLine()) != null){
sb.append(response);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, String> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
}
Это зависит от того, какой из них выбрать, зависит от требований
Обработчик в основном используется для переключения с другого потока на основной поток. Обработчик прикреплен к циклу, на котором он помещает свою выполняемую задачу в очередь. Итак, если вы уже находитесь в другом потоке и переключаетесь на основной поток, вам нужен обработчик вместо задачи async или другого потока
Если обработчик, созданный не в основном потоке, а не в цикле, не выдаст ошибку, поскольку дескриптор создается в потоке, этот поток необходимо сделать лоппером
AsyncTask используется для выполнения кода в течение нескольких секунд, который выполняется в фоновом потоке и передает свой результат в основной поток ** * Ограничения AsyncTask 1. Асинхронная задача не привязана к жизненному циклу активности и продолжает выполняться, даже если ее активность уничтожена, тогда как загрузчик не нет этого ограничения 2. Все асинхронные задачи используют один и тот же фоновый поток для выполнения, что также влияет на производительность приложения.
Поток также используется в приложении для фоновой работы, но у него нет обратного вызова в основном потоке. Если требование подходит для нескольких потоков, а не для одного потока и которые должны выполнять задачу много раз, то лучше использовать исполнитель пула потоков. Например, требование загрузки изображения с нескольких URL-адресов, таких как скольжение.
Позвольте мне попытаться ответить на вопрос здесь на примере:) - 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 я мог придумать варианты:
- Вариант 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);
}
}
Я надеюсь, что мой ответ, хотя долго, поможет в понимании некоторых более мелких деталей.
Нить
Когда вы запускаете приложение, создается процесс для выполнения кода. Чтобы эффективно использовать вычислительный ресурс, потоки могут быть запущены внутри процесса, чтобы одновременно можно было выполнить несколько задач. Таким образом, потоки позволяют создавать эффективные приложения, эффективно используя процессор без простоев.
В Android все компоненты выполняются в одном основном потоке. Задачи очереди Android и выполняйте их одну за другой в главном потоке. Когда долго выполняющиеся задачи выполняются, приложение перестает отвечать на запросы.
Чтобы предотвратить это, вы можете создавать рабочие потоки и запускать фоновые или долго выполняющиеся задачи.
укротитель
Поскольку android использует модель с одним потоком, компоненты пользовательского интерфейса создаются не поточно-безопасными. Это означает, что доступ к ним должен иметь только созданный им поток, то есть компонент пользовательского интерфейса должен обновляться только в основном потоке. Поскольку компонент пользовательского интерфейса выполняется в основном потоке, задачи, выполняемые в рабочих потоках, не могут изменять компоненты пользовательского интерфейса. Это где Handler входит в картину. Обработчик с помощью Looper может подключиться к новому потоку или существующему потоку и запустить код, который он содержит в подключенном потоке.
Обработчик делает возможным взаимодействие между потоками. Используя обработчик, фоновый поток может отправлять результаты в него, а обработчик, подключенный к основному потоку, может обновлять компоненты пользовательского интерфейса в основном потоке.
AsyncTask
AsyncTask, предоставляемый android, использует как поток, так и обработчик для упрощения выполнения простых задач в фоновом режиме и обновления результатов из фонового потока в основной поток.
Пожалуйста, смотрите Android Thread, Handler, Asynctask и Пулы потоков для примеров.
Handler
- это средство связи между потоками. В Android он в основном используется для связи с основным потоком, создавая и отправляя сообщения через обработчик
AsyncTask
- используется для выполнения долго работающих приложений в фоновом потоке. С пAsyncTask
вы можете выполнить операцию в фоновом потоке и получить результат в основном потоке приложения.
Thread
- это легкий процесс для достижения параллелизма и максимального использования процессора. В Android вы можете использовать поток для выполнения действий, которые не касаются пользовательского интерфейса приложения