Android: AsyncTask vs Service


138

Чому я читаю у відповіді на більшість питань тут багато про AsyncTaskта навантажувачі, але нічого про послуги ? Служби просто не відомі дуже добре, або вони застаріли, або мають погані атрибути чи щось таке? Які відмінності?

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

Відповіді:


272

В деяких випадках можна виконати одне і те ж завдання або з AsyncTaskодним, Serviceпроте, як правило, одне краще підходить до задачі, ніж інше.

AsyncTasks призначені для одноразових трудомістких завдань, які неможливо виконати з потоку інтерфейсу. Поширений приклад - отримання / обробка даних при натисканні кнопки.

Services призначені для постійного запуску у фоновому режимі. У наведеному вище прикладі отримання даних при натисканні кнопки ви можете запустити службу, дозволити їй отримати дані, а потім зупинити її, але це неефективно. Набагато швидше використовувати один, AsyncTaskякий буде запущений один раз, повернути дані та зробити це.

Якщо вам потрібно постійно робити щось у фоновому режимі, Serviceце найкраще. Приклади цього можуть відтворювати музику, постійно перевіряти наявність нових даних тощо.

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

Здебільшого, Services призначені для запуску коду, навіть коли програма Activityне відкрита. AsyncTasks призначені для того, щоб зробити код виконання від потоку інтерфейсу неймовірно простим.


2
Цікаво, що в цій розмові від Google I / O в 2010 youtube.com/watch?v=xHXn3Kg2IQE презентатор надає 3 різні методи отримання даних з API REST, і перший використовує послугу. Я не експерт з Android, але також мав враження, що те, що сказав Computerish, є в основному правильним.
wuliwong

10
Останній абзац: "Служби призначені для запуску коду, навіть коли активність програми не відкрита". Це також стосується AsyncTask або фонових потоків. наприклад, коли ви натискаєте назад у своїй діяльності або закінчуєте дзвінки (), і ваша діяльність не видно, але фонові потоки виконуються доти, доки ви не вб'єте ваш додаток (наприклад, замінивши останніми завданнями). Я перевірив це на 4.4.2
гурток

10
Однак AsyncTask може бути складним, якщо активність, яка його розпочала, знищена, поки AsyncTask все ще запущена та потребує оновлення інтерфейсу користувача, як тільки це буде зроблено ... (що не буде працювати, оскільки діяльність вже знищена). Чому б не скористатись IntentService, який не потребує зупинки вручну, оскільки він просто закінчується після завершення?
AgentKnopf

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

3
@LarsH Виправте мене, якщо я помиляюся, але я думаю, що ви можете використовувати BroadcastReceiver у своїй діяльності / фрагменті, а з IntentService ви просто запустіть трансляцію, коли закінчите. Оскільки ви можете перереєструватися для трансляцій після відновлення діяльності / фрагментів, які повинні охопити вас. Іншою альтернативою може бути використання EventBus для оновлення інтерфейсу користувача (хоча я намагаюся уникати цього - ускладнює код слідувати за imo).
AgentKnopf

58

Послуги абсолютно різні: Послуги не є нитками !

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


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

Просто думка: У сервісу може бути AsyncTaskоб’єкт!


2
Служби описуються як запущені у фоновому режимі, але вони продовжуються навіть тоді, коли програма ур закрита. AsyncTask також використовується для того, щоб робити щось у фоновому режимі. Знаєте, що я маю на увазі?
erikbwork

1
так, але служби можуть щось робити чи не робити. Вони є довготривалим
ОБ'Єктом

"У сервісі може бути об'єкт AsyncTask!" Дякуємо, що вказали на це. Але чи гарна ідея - це щось, що ви б порадили? Або краще було б використовувати більш базові методи нарізання різьби в сервісі?
RenniePet

"Ваша активність прив'язується до послуги" не обов'язково.
JacksOnF1re

@ JacksOnF1re Я знаю, що це так, коли я вперше почав кодування: p, але "Ваша діяльність прив'язується до послуги" - це правдиве твердження. Я також можу бути обов'язковим до цієї послуги. Холодильник також може бути обов'язковим. Це не робить заяву недійсною. У будь-якому випадку jk
Шериф ель-Катіб

7

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

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


чи можете ви вказати, чому ви думаєте, що ваша відповідь щось додає до питання?
erikbwork

2
інші відповіді або занадто короткі, або занадто довгі, щоб новачки зрозуміли. тож я відповів точно простими словами на прикладах
арджун

6

Сервіс та асинтакси майже роблять одне і те ж, майже .використовуючи сервіс чи асинтакт, залежить від того, яка ваша вимога.

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

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

щасливе кодування.


1
Привіт Ашана, чи можу я запитати, чому ти дав цю відповідь на питання, на яке вже відповіли? Ви незадоволені наявною позначеною відповіддю? Або ви намагаєтесь створити профіль SO, написавши свою думку на всі питання, про які є що сказати? Або щось зовсім інше? Не можу це зрозуміти, але я часто бачу цей малюнок останнім часом.
erikbwork

3
я знаю, відповідь вже дана, і я не бачу тут багато проблем, якщо я даю правильну відповідь чи свою думку тут, брато? тому що ви не єдиний, хто шукає відповідь на те саме запитання, якщо комусь важко зрозуміти рішення в наведених вище відповідях, він / вона може прокрутити вниз до пошуку відповіді, яка їм добре підходить, легко зрозуміти її. Це так. Дякую за коментар брато, я не геній чи професіонал у програмуванні, просто хочу допомогти іншим, спробуйте навчити інших тому, що я вже знаю :)
Ashana.Jackol

1

У кількох випадках ви можете досягти однакової функціональності, використовуючи обидва. На відміну від Async Task, сервіс має власний життєвий цикл і успадковує контекст (служба є більш надійною, ніж завдання Async). Сервіс може працювати навіть у тому випадку, якщо ви закрили додаток. Якщо ви хочете щось зробити навіть після закриття програми, а також вам потрібна змінна контекст, ви перейдете до служби.

Приклад: Якщо ви хочете відтворити музику, і ви не хочете робити паузу, якщо користувач покине додаток, ви обов'язково перейдете до Сервісу.


1

Порівняння локального, базового класу Сервіс ✱ з AsyncTask:

✱ (Ця відповідь не стосується експортованих послуг або будь-якої послуги, яка працює в процесі, відмінному від клієнта, оскільки очікувані випадки використання істотно відрізняються від випадків AsyncTask. Також, в інтересах стислості, характеру певних спеціалізованих Serviceпідкласи (наприклад, IntentService, JobService) будуть проігноровані тут.)

Тривалість процесу

A Serviceпредставляє для ОС "бажання програми виконувати більш тривалу операцію, не взаємодіючи з користувачем" [ ref ].

Хоча у вас Serviceпрацює, Android розуміє, що ви не хочете, щоб ваш процес був убитий. Це також справедливо щоразу, коли у вас є Activityекран, і це особливо вірно, коли ви виконуєте службу переднього плану . (Коли всі компоненти вашого додатка відійдуть, Android думає: "О, зараз саме час вбити цю програму, тому я можу звільнити ресурси".)

Крім того, залежно від останнього значення, що повертається Service.onCreate(), Android може спробувати "оживити" додатки / послуги, які були вбиті через тиск на ресурси [ ref ].

AsyncTasksне роби нічого з цього. Не має значення, скільки фонових потоків у вас запущено чи наскільки вони працюють: Android не буде підтримувати вашу програму в живих лише тому, що ваш додаток використовує процесор. Він повинен мати певний спосіб дізнатися, що у вашому додатку ще належить виконати роботу; тому Servicesзареєстровані в ОС, а AsyncTasksні.

Багатопотоковість

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

Кожне нове AsyncTaskвиконання, як правило, призводить до більшої сумісності (більше ниток), за умови обмеження AsyncTasks'sпулу потоків [ ref ].

ServiceМетоди, з іншого боку, завжди викликаються у потоці інтерфейсу користувача [ ref ]. Це відноситься і до onCreate(), onStartCommand(), onDestroy(), onServiceConnected()і т.д. Таким чином, в певному сенсі, Servicesне "запустити" в фоновому режимі. Після запуску ( onCreate()) вони просто "сидять" там - поки не прийде час прибрати, виконати і onStartCommand()т.д.

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

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

Якщо ви хочете додати фонову нитку (або якусь іншу роботу) Service, ви можете це зробити. Ви можете почати фоновий потік / AsyncTaskв Service.onCreate(), наприклад. Але не всі випадки використання цього вимагають. Наприклад:

  • Ви можете продовжувати Serviceпрацювати, щоб ви могли продовжувати отримувати оновлення місця у "фоновому режимі" (мається на увазі, не маючи на Activitiesекрані жодного ).
  • Або, можливо, ви хочете, щоб ваш додаток залишався в живих лише для того, щоб ви могли BroadcastReceiverтривалий час зберігати "неявну" реєстрацію (після API 26 ви не завжди можете це зробити через маніфест, тому вам доведеться зареєструватися під час виконання [ ref ]).

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

Як робітники

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

Зверніть увагу , що AsyncTaskце планується для старіння . Але це не означає , що вам слід замінити ваші AsyncTasksз Services! (Якщо ви дізналися що-небудь з цієї відповіді, то багато чого повинно бути зрозумілим.)

TL; DR

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

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