Мене бентежить, коли можна вибрати AsyncTask через обробник. Скажіть, у мене є якийсь код, який я хочу запускати кожні n секунд, який оновлюватиме інтерфейс користувача. Чому я обрав би один над іншим?
Мене бентежить, коли можна вибрати AsyncTask через обробник. Скажіть, у мене є якийсь код, який я хочу запускати кожні n секунд, який оновлюватиме інтерфейс користувача. Чому я обрав би один над іншим?
Відповіді:
IMO, AsyncTask був написаний, щоб забезпечити зручний, простий у використанні спосіб домогтися фонової обробки в додатках для Android, не турбуючись надто про деталі низького рівня (теми, петлі повідомлень тощо). Він надає методи зворотного виклику, які допомагають планувати завдання, а також легко оновлювати інтерфейс користувача, коли це потрібно.
Однак важливо зауважити, що при використанні AsyncTask розробник дотримується своїх обмежень, наслідком яких є проектні рішення, які приймав автор класу. Наприклад, недавно я з'ясував, що існує обмеження кількості завдань, які можна запланувати за допомогою AsyncTasks.
Хендлер більш прозорий з цих двох і, ймовірно, дає більше свободи; тому, якщо ви хочете більше контролювати речі, ви вибрали б Handler, інакше AsynTask буде працювати чудово.
AsyncTasksвони виконуються на одній нитці, тому більше немає паралелізму. Ви все одно можете запустити їх на паралельній Executorреалізації.
Моє правило:
Якщо ви робите щось відокремлене, пов’язане з інтерфейсом користувача, наприклад, завантажуючи дані для представлення у списку, продовжуйте користуватися AsyncTask.
Якщо ви виконуєте кілька повторних завдань, наприклад завантажуєте декілька зображень, які мають відображатися ImageViews(наприклад, завантаження мініатюр) після завантаження, використовуйте чергу завдань за допомогою Handler.
Завжди намагайтеся уникати використання AsyncTask, коли це можливо, в основному з наступних причин:
AsyncTask не гарантується, оскільки система базу ThreadPool і максимальний розмір встановлені системою, і якщо ви створите занадто багато асинтакта, вони з часом будуть знищені
AsyncTask може бути автоматично припинено навіть під час запуску, залежно від життєвого циклу діяльності, і ви не маєте контролю над ним
Методи AsyncTask, що працюють на потоці користувальницького інтерфейсу, як onPostExecute, можуть бути виконані, коли діяльність, на яку вона посилається, більше не видно, або, можливо, в іншому стані компонування, як, наприклад, після зміни орієнтації.
На закінчення ви не повинні використовувати пов'язані з UIThread методи AsyncTask, що є його основною перевагою !!! Крім того, вам слід робити лише не критичну роботу на doInBackground. Прочитайте цю тему, щоб отримати докладнішу інформацію про ці проблеми:
Невже AsyncTask є концептуально помилковим чи мені просто щось не вистачає?
На закінчення спробуйте віддати перевагу використанню IntentServices, HandlerThread або ThreadPoolExecutor замість AsyncTask, коли будь-яка з перерахованих вище проблем може турбувати вас. Звичайно, це вимагатиме більше роботи, але ваша програма буде більш безпечною.
Якщо ви хочете робити обчислення кожні х секунд, ви, ймовірно, повинні запланувати a Runnableна Handler(з postDelayed()), і це Runnableмає починатися в поточному потоці інтерфейсу. Якщо ви хочете запустити його в іншій нитці, використовуйте HandlerThread. AsyncTask простіший у використанні для нас, але не кращий за обробник.
Обробник пов'язаний з основною темою програми. він обробляє і планує повідомлення та розгорнуті повідомлення, що надсилаються з фонових потоків до головної нитки програми
AsyncTask пропонує простий метод обробки фонових потоків, щоб оновити інтерфейс користувача, не блокуючи його трудомісткими операціями.
Відповідь полягає в тому, що обидва можна використовувати для оновлення інтерфейсу користувача з фонових потоків, різниця буде у вашому сценарії виконання. Ви можете розглянути можливість використання обробника, який ви хочете розміщувати із затримкою або надсилати повідомлення до черги повідомлень у певному порядку.
Ви можете розглянути можливість використання AsyncTask, якщо ви бажаєте легко обміняти параметри (таким чином оновляючи інтерфейс користувача) між основною ниткою програми та фоновою ниткою.
AsyncTaskприпускає, що ви зробите щось із потоку інтерфейсу користувача, після того як деякі фонові роботи будуть закінчені. Крім того, ви можете виконати його лише один раз (після цього його статус є, FINISHEDі ви отримаєте виняток, намагаючись виконати його ще раз). Також гнучкість його використання не велика. Так, ви можете використовувати THREAD_POOL_EXECUTORдля паралельного виконання, але зусилля можуть бути не вартими.
Handlerне передбачає нічого, крім обробки Runnables і Messages. Крім того, його можна запускати стільки разів, скільки ви бажаєте . Ви можете вирішити, до якої нитки він повинен бути прикріплений, як він спілкується з іншими обробниками, можливо, виробляє їх HandlerThread. Отже, він набагато гнучкіший і підходить для деяких повторних робіт.
Ознайомтеся з різними Handlerприкладами тут .
Вони є найкращим питанням інтерв'ю, яке задають. AsyncTask - Вони використовуються для завантаження потоку інтерфейсу та виконання завдань у фоновому режимі. Обробники - Android дозант має прямий спосіб зв'язку між інтерфейсом користувача та фоновим потоком. Обробники повинні використовуватися для надсилання повідомлень або запуску через чергу повідомлень.
Отже, AsyncTasks використовуються там, де завдання потрібно виконати у фоновому режимі, а обробники використовуються для зв'язку між інтерфейсом користувача та фоновою ниткою.
doInBackground - в основному працює в іншій нитці. onPostExecute - розміщує результати на потоці користувальницького інтерфейсу, і воно внутрішньо надсилає повідомлення на обробник основного потоку. Головний потік інтерфейсу вже має петлю та оброблювач, пов'язаний з ним.
Отже, якщо вам потрібно виконати якесь фонове завдання, використовуйте AsyncTask. Але в кінцевому підсумку, якщо щось потрібно оновити в інтерфейсі користувача, воно буде використовувати обробник основного потоку.