Обробник проти AsyncTask


128

Мене бентежить, коли можна вибрати AsyncTask через обробник. Скажіть, у мене є якийсь код, який я хочу запускати кожні n секунд, який оновлюватиме інтерфейс користувача. Чому я обрав би один над іншим?


1
Це стало складніше з AsyncTaskLoaders. Дивіться stackoverflow.com/q/7120813/969325 для отримання додаткової інформації.
Warpzit

Відповіді:


75

IMO, AsyncTask був написаний, щоб забезпечити зручний, простий у використанні спосіб домогтися фонової обробки в додатках для Android, не турбуючись надто про деталі низького рівня (теми, петлі повідомлень тощо). Він надає методи зворотного виклику, які допомагають планувати завдання, а також легко оновлювати інтерфейс користувача, коли це потрібно.

Однак важливо зауважити, що при використанні AsyncTask розробник дотримується своїх обмежень, наслідком яких є проектні рішення, які приймав автор класу. Наприклад, недавно я з'ясував, що існує обмеження кількості завдань, які можна запланувати за допомогою AsyncTasks.

Хендлер більш прозорий з цих двох і, ймовірно, дає більше свободи; тому, якщо ви хочете більше контролювати речі, ви вибрали б Handler, інакше AsynTask буде працювати чудово.


Це вірно. Я використовував AsyncTasks для всіх фонових операцій у своєму проекті. У якийсь момент я почав досягати межі максимальної кількості робочих місць, тому мої завдання розпочнуться лише після закінчення іншої. Врешті-решт мені довелося змінити всю свою структуру, щоб перестати використовувати асинтакти і уникати цього обмеження.
tbraun

5
З соти далі, AsyncTasksвони виконуються на одній нитці, тому більше немає паралелізму. Ви все одно можете запустити їх на паралельній Executorреалізації.
MrSnowflake

63

Моє правило:

  • Якщо ви робите щось відокремлене, пов’язане з інтерфейсом користувача, наприклад, завантажуючи дані для представлення у списку, продовжуйте користуватися AsyncTask.

  • Якщо ви виконуєте кілька повторних завдань, наприклад завантажуєте декілька зображень, які мають відображатися ImageViews(наприклад, завантаження мініатюр) після завантаження, використовуйте чергу завдань за допомогою Handler.


Обробник знаходиться в рівні API 1 та ASYNCTASK на рівні 3 API, чи буде його застаріло будь-якою ціною? Беказ зосереджуюсь на перенесенні програм із старих версій до 2.2 та 2.3 ..
yokks

10
Жоден з них не буде порушеним. Обробник ніколи не буде застарілим, оскільки інтерфейс користувача в основному побудований навколо нього.
alexanderblom

Чи не слід використовувати навантажувач для завантаження даних, що пред'являються до вашого інтерфейсу?
nbarraille

19

Завжди намагайтеся уникати використання AsyncTask, коли це можливо, в основному з наступних причин:

  • AsyncTask не гарантується, оскільки система базу ThreadPool і максимальний розмір встановлені системою, і якщо ви створите занадто багато асинтакта, вони з часом будуть знищені

  • AsyncTask може бути автоматично припинено навіть під час запуску, залежно від життєвого циклу діяльності, і ви не маєте контролю над ним

  • Методи AsyncTask, що працюють на потоці користувальницького інтерфейсу, як onPostExecute, можуть бути виконані, коли діяльність, на яку вона посилається, більше не видно, або, можливо, в іншому стані компонування, як, наприклад, після зміни орієнтації.

На закінчення ви не повинні використовувати пов'язані з UIThread методи AsyncTask, що є його основною перевагою !!! Крім того, вам слід робити лише не критичну роботу на doInBackground. Прочитайте цю тему, щоб отримати докладнішу інформацію про ці проблеми:

Невже AsyncTask є концептуально помилковим чи мені просто щось не вистачає?

На закінчення спробуйте віддати перевагу використанню IntentServices, HandlerThread або ThreadPoolExecutor замість AsyncTask, коли будь-яка з перерахованих вище проблем може турбувати вас. Звичайно, це вимагатиме більше роботи, але ваша програма буде більш безпечною.


Так, я витратив багато часу, шкодуючи про багато використання AsyncTasks. Вони здаються чудовими, але ... стільки проблем!
SMBiggs

6
Мені шкода, що настільки сильно розміщую проти ваших точок, але я не можу дозволити вашому поганому стильному ефекту нубі до андроїда. Точка перша. У вас НЕ повинно працювати стільки потоків. Якщо ви стикаєтесь з цим, ваша архітектура є foobar. Точка 2. Як на землі? Добре, так, все в android - це безкоштовна гра до сміттєзбірника ... Ви бачили б лише відхилену поведінку, як описано вище, у деяких суворо зловживаючих випадках. Пункт 3. Управління своїм завданням, не бути грубим, - це навичка початківця. Ви або вбиваєте його під час дзвінка на Паузу, або належним чином від'єднуєтесь та приєднуєтесь відповідно.
StarWind0

1
vogella.com/tutorials/AndroidBackgroundProcessing/article.html Це все, що потрібно для того, щоб навчитися правильно виконувати завдання без вищезазначених питань (якщо припустити, що ви не робите щось на кшталт того, як виконувати кілька сотень завдань)
StarWind0

16

Якщо ви хочете робити обчислення кожні х секунд, ви, ймовірно, повинні запланувати a Runnableна HandlerpostDelayed()), і це Runnableмає починатися в поточному потоці інтерфейсу. Якщо ви хочете запустити його в іншій нитці, використовуйте HandlerThread. AsyncTask простіший у використанні для нас, але не кращий за обробник.


7

Обробник пов'язаний з основною темою програми. він обробляє і планує повідомлення та розгорнуті повідомлення, що надсилаються з фонових потоків до головної нитки програми

AsyncTask пропонує простий метод обробки фонових потоків, щоб оновити інтерфейс користувача, не блокуючи його трудомісткими операціями.

Відповідь полягає в тому, що обидва можна використовувати для оновлення інтерфейсу користувача з фонових потоків, різниця буде у вашому сценарії виконання. Ви можете розглянути можливість використання обробника, який ви хочете розміщувати із затримкою або надсилати повідомлення до черги повідомлень у певному порядку.

Ви можете розглянути можливість використання AsyncTask, якщо ви бажаєте легко обміняти параметри (таким чином оновляючи інтерфейс користувача) між основною ниткою програми та фоновою ниткою.


3
Ви можете створити власний обробник, пов’язаний з іншою темою.
Олексій Мджалікс

Обробник не обов'язково прив’язаний до основної нитки (UI Thread). Він прив’язаний до потоку, в якому він був створений, і обробляє повідомлення або повідомлення, які надходять до цієї черги повідомлень потоку. Він також може надсилати об'єкти Message і Runnable до цієї черги повідомлень потоку.
azec-pdx

2

AsyncTaskприпускає, що ви зробите щось із потоку інтерфейсу користувача, після того як деякі фонові роботи будуть закінчені. Крім того, ви можете виконати його лише один раз (після цього його статус є, FINISHEDі ви отримаєте виняток, намагаючись виконати його ще раз). Також гнучкість його використання не велика. Так, ви можете використовувати THREAD_POOL_EXECUTORдля паралельного виконання, але зусилля можуть бути не вартими.

Handlerне передбачає нічого, крім обробки Runnables і Messages. Крім того, його можна запускати стільки разів, скільки ви бажаєте . Ви можете вирішити, до якої нитки він повинен бути прикріплений, як він спілкується з іншими обробниками, можливо, виробляє їх HandlerThread. Отже, він набагато гнучкіший і підходить для деяких повторних робіт.

Ознайомтеся з різними Handlerприкладами тут .


0

Вони є найкращим питанням інтерв'ю, яке задають. AsyncTask - Вони використовуються для завантаження потоку інтерфейсу та виконання завдань у фоновому режимі. Обробники - Android дозант має прямий спосіб зв'язку між інтерфейсом користувача та фоновим потоком. Обробники повинні використовуватися для надсилання повідомлень або запуску через чергу повідомлень.

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


0

doInBackground - в основному працює в іншій нитці. onPostExecute - розміщує результати на потоці користувальницького інтерфейсу, і воно внутрішньо надсилає повідомлення на обробник основного потоку. Головний потік інтерфейсу вже має петлю та оброблювач, пов'язаний з ним.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.