Я не понимаю, когда можно выбрать AsyncTask вместо Handler. Скажем, у меня есть код, который я хочу запускать каждые n секунд, чтобы обновлять пользовательский интерфейс. Почему я должен предпочесть одно другому?
Я не понимаю, когда можно выбрать AsyncTask вместо Handler. Скажем, у меня есть код, который я хочу запускать каждые n секунд, чтобы обновлять пользовательский интерфейс. Почему я должен предпочесть одно другому?
Ответы:
IMO, AsyncTask был написан, чтобы обеспечить удобный и простой в использовании способ достижения фоновой обработки в приложениях Android, не беспокоясь о деталях низкого уровня (потоки, циклы сообщений и т. Д.). Он предоставляет методы обратного вызова, которые помогают планировать задачи, а также легко обновлять пользовательский интерфейс при необходимости.
Однако важно отметить, что при использовании AsyncTask разработчик подчиняется его ограничениям, которые возникают из-за проектных решений, принятых автором класса. Например, я недавно узнал, что существует ограничение на количество заданий, которые можно запланировать с помощью AsyncTasks.
Handler более прозрачен из двух и, вероятно, дает вам больше свободы; поэтому, если вам нужен больший контроль над вещами, вы должны выбрать Handler, иначе AsynTask будет работать нормально.
AsyncTasksони выполняются в одном потоке, поэтому параллелизма больше нет. Вы по-прежнему можете запускать их в параллельной Executorреализации.
Мое практическое правило:
Если вы делаете что-то изолированное, связанное с пользовательским интерфейсом, например загружаете данные для представления в списке, продолжайте и используйте AsyncTask.
Если вы выполняете несколько повторяющихся задач, например загружаете несколько изображений, которые должны отображаться ImageViews(например, загружать эскизы) при загрузке, используйте очередь задач с Handler.
Всегда старайтесь избегать использования AsyncTask, когда это возможно, в основном по следующим причинам:
AsyncTask не гарантированно запускается, так как существует база ThreadPool и максимальный размер, установленный системой, и если вы создадите слишком много asynctask, они в конечном итоге будут уничтожены
AsyncTask может быть автоматически завершен, даже во время работы, в зависимости от жизненного цикла активности, и вы не можете его контролировать.
Методы AsyncTask, работающие в потоке пользовательского интерфейса, такие как onPostExecute, могут выполняться, когда действие, на которое оно ссылается, больше не отображается или, возможно, находится в другом состоянии макета, например, после изменения ориентации.
В заключение вы не должны использовать связанные с UIThread методы AsyncTask, что является его основным преимуществом !!! Более того, над doInBackground следует выполнять некритическую работу. Прочтите эту ветку, чтобы узнать больше об этих проблемах:
Действительно ли AsyncTask концептуально ошибочен или я просто что-то упускаю?
В заключение попробуйте предпочесть использование IntentServices, HandlerThread или ThreadPoolExecutor вместо AsyncTask, когда любая из вышеперечисленных проблем может вас беспокоить. Конечно, это потребует дополнительной работы, но ваше приложение будет безопаснее.
Если вы хотите выполнять вычисления каждые x секунд, вам, вероятно, следует запланировать a Runnableна Handler(with postDelayed()), и это Runnableдолжно начаться в текущем потоке пользовательского интерфейса. Если вы хотите запустить его в другом потоке, используйте HandlerThread. AsyncTask нам проще использовать, но не лучше обработчика.
Обработчик связан с основным потоком приложения. он обрабатывает и планирует сообщения и исполняемые файлы, отправляемые из фоновых потоков в основной поток приложения.
AsyncTask предоставляет простой метод обработки фоновых потоков для обновления пользовательского интерфейса, не блокируя его трудоемкими операциями.
Ответ заключается в том, что оба могут использоваться для обновления пользовательского интерфейса из фоновых потоков, разница будет в вашем сценарии выполнения. Вы можете использовать обработчик, если хотите публиковать отложенные сообщения или отправлять сообщения в MessageQueue в определенном порядке.
Вы можете рассмотреть возможность использования AsyncTask, если хотите легко и удобно обмениваться параметрами (таким образом, обновляя пользовательский интерфейс) между основным потоком приложения и фоновым потоком.
AsyncTaskпредполагает, что вы что-то сделаете в потоке пользовательского интерфейса после завершения некоторой фоновой работы. Кроме того, вы можете выполнить его только один раз (после этого его статус будет, FINISHEDи вы получите исключение, пытающееся выполнить его еще раз). К тому же гибкость его использования невелика. Да, можно использовать THREAD_POOL_EXECUTORдля параллельного выполнения, но усилия могут быть не достойными.
Handlerне предполагает ничего, кроме обработки Runnables и Messages. Кроме того, его можно запускать сколько угодно раз . Вы можете решить, к какому потоку он должен быть присоединен, как он взаимодействует с другими обработчиками, возможно, с их помощью HandlerThread. Таким образом, он намного более гибкий и подходит для повторяющейся работы.
Проверьте различные виды Handlerпримеров здесь .
Это лучший вопрос на собеседовании. AsyncTask - они используются для разгрузки потока пользовательского интерфейса и выполнения задач в фоновом режиме. Обработчики - Android dosent имеет прямой способ связи между пользовательским интерфейсом и фоновым потоком. Обработчики должны использоваться для отправки сообщения или запускаться через очередь сообщений.
Таким образом, AsyncTasks используются там, где задачи должны выполняться в фоновом режиме, а обработчики используются для связи между пользовательским интерфейсом и фоновым потоком.
doInBackground - в основном работает в другом потоке. onPostExecute - публикует результаты в потоке пользовательского интерфейса и внутренне отправляет сообщение обработчику основного потока. Основной поток пользовательского интерфейса уже имеет связанный с ним цикл и обработчик.
В общем, если вам нужно выполнить какую-то фоновую задачу, используйте AsyncTask. Но в конечном итоге, если что-то нужно обновить в пользовательском интерфейсе, он будет использовать обработчик основного потока.