Обработчик против AsyncTask против темы [закрыто]


382

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

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

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

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

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

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



9
«Обработчики - это фоновые темы». Некоторые ответы, получившие наибольшее количество голосов, похоже, тоже идут в этом направлении. Но это заблуждение. A Handlerне является потоком, и он ничего не выполняет. Это всего лишь средство для безопасной передачи сообщений из одного потока в очередь сообщений другого потока . Таким образом, обычно (по крайней мере) еще два потока должны быть созданы, которые затем могут использовать обработчик, но обработчик не может ничего выполнить сам.
JimmyB

Ответы:


57

Как говорится в Руководстве по фоновой обработке 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: лекция Дугласа Шмидта android параллелизм и синхронизация

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

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

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

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


4
В этой серии лекций эта ссылка приведет вас прямо к нескольким примерам веток
Aggressor

353

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

Так что нет волшебства в AsyncTaskили Handler. Эти занятия делают нашу жизнь проще как разработчик.

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

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

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

Итак, каковы различия между Thread, AsyncTaskи Handler?

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

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

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

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

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

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

Я хочу подчеркнуть два момента:

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

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

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

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

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

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

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


4
фактически asynctask также основан на обработчике и futuretask, см.
Sumit

AsyncTask по сути является вспомогательным классом, построенным поверх Handler и Thread. developer.android.com/reference/android/os/AsyncTask.html . Посмотрите на документ «AsyncTask разработан как вспомогательный класс для Thread и Handler». AsyncTask выпущен в API3, а обработчик существует начиная с API1.
hjchin

52

После тщательного изучения, это прямо вперед.

AsyncTask:

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

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

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

Handler:

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

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

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

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

Thread:

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

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


1
На самом деле AsyncTask api написан с использованием Futures, Handlers и Executors. См. Исходный код: grepcode.com/file_/repository.grepcode.com/java/ext/…
Игорь Ганапольский

22

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

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


9

Нить

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


6

Thread:

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

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

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

Обработчик :

A 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являются лучшим вариантом. Поскольку вы должны поддерживать сокетное соединение, обработчик в главном потоке вообще бесполезен. Создайте 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: тост в потоке


5

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

ОБНОВИТЬ

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

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


спасибо, есть ли причина, по которой я должен использовать Threads вместо AsyncTasks? Или лучше его использовать?
Alx

9
@AeroDroid В вашем примере: «простое время (true)», вы будете привязывать ЦП здесь, если вы не добавите спящее состояние в цикл. Это верно для любого бесконечного цикла. Если вы хотите уменьшить загрузку ЦП из-за этих издержек, спите поток в течение нескольких миллисекунд в конце цикла.
Ошибка 454

1
@ Ошибка 454 - это интересно! Если бы вам нужно было выбрать подходящее число для времени сна, это было бы между 40-80 миллисекундами?
Абхиджит

6
@Abhijit Из всего, что я сделал в SDL, просто добавив 10-миллисекундный цикл в цикл, достаточно было упасть с 99% ЦП до ~ 0 во время простоя.
Ошибка 454

15
На самом деле developer.android.com/reference/android/os/AsyncTask.html говорит: «AsyncTasks в идеале следует использовать для коротких операций». Вы должны также использовать их осторожно, так как они могут быть отклонены системой без выполнения!
type-a1pha

5

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


2
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();
    }

}

1

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

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);
    }
}

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


Могу ли я узнать причину, по которой мое объяснение на основе примера для аналогии было отвергнуто, чтобы я также мог извлечь из него урок?
Акшаймани

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

@ 80leaves хорошо, теперь я понял, я пытался объяснить, как я пришел к выводу о том, что нужно выбрать один путь перед другим. В любом случае, хотелось бы услышать ваши / другие мнения о том, правильно ли написанное мной или может быть улучшено в дальнейшем.
Акшаймани

1

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

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

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

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

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


0

Нить

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

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

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

укротитель

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

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

AsyncTask

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

Пожалуйста, смотрите Android Thread, Handler, Asynctask и Пулы потоков для примеров.


-1

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.