Сервіс проти IntentService на платформі Android


774

Я шукаю приклад того, що можна зробити із тим, IntentServiceщо неможливо зробити за допомогою Service(і навпаки)?

Я також вважаю, що IntentServiceпробіг в іншій нитці, а а Serviceні. Тож, наскільки я бачу, запуск послуги у власній нитці - це як початок IntentService. Це правильно?


45
IntentService is used for short tasks (etc) and a service is for long onesде ти це читав?
njzk2

9
aТакже я пропоную прочитати вихідний код для IntentService. Це дає зрозуміти, що це таке і що робить.
njzk2

1
Я редагував своє запитання після того, як побачив, як ви коментуєте.
roiberg


2
Посилання в попередньому коментарі (автор greg7gkb) - це чудове прочитання.
DSlomer64

Відповіді:


1348

Техас Лагванкар написав приємний пост на цю тему. Нижче наведено кілька ключових відмінностей між Сервісом та IntentService.

Коли користуватися?

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

  • Служба IntentService може використовуватися в довгих завданнях, як правило, без зв'язку з основною темою . Якщо потрібне спілкування, можна використовувати оброблювач Main Thread або широкомовні трансляції. Інший випадок використання - це коли потрібні зворотні виклики (Завдання, що спрацьовують з наміром).

Як запустити?

  • Служба запускається з допомогою виклику методу startService().

  • Служба IntentService запускається за допомогою Intent, вона породжує новий робочий потік і метод onHandleIntent()викликається на цій нитці.

Запущено

  • Обслуговування і IntentService можуть бути викликані з будь-якого потоку, активності або іншого компонента програми.

Працює

  • Служба працює у фоновому режимі , але він працює на головному потоці програми.

  • Служба IntentService працює на окремій робочій нитці.

Обмеження / Недоліки

  • Служба може блокувати головний потік програми.

  • IntentService не може виконувати завдання паралельно. Отже, всі послідовні наміри будуть входити в чергу повідомлень для робочої нитки та виконуватимуться послідовно.

Коли зупинитись?

  • При реалізації служби , це ваша відповідальність , щоб зупинити службу , коли робота закінчена, зателефонувавши по телефону stopSelf()або stopService(). (Якщо ви хочете лише надати прив'язку, вам не потрібно реалізовувати цей метод).

  • IntentService зупиняє службу після того, як всі запити початку були оброблені, так що ви ніколи не повинні викликом stopSelf().


11
коротка і мила, але краще, якщо ви будете редагувати свою відповідь, включаючи пункти CommonsWare, оскільки багато людей читають лише прийняті або найвигідніші відповіді
Shirish Herwade

12
@Darpan A Service - це компонент програми, який може виконувати тривалі операції у фоновому режимі і не забезпечує інтерфейс користувача. Послуга працює в основному потоці хостингу. Сервіс не створює власний потік і не працює в окремому процесі (якщо не вказано інше). Це означає, що якщо ваша служба буде виконувати будь-які оперативні роботи або блокування процесора (наприклад, відтворення MP3 або мережа), вам слід створити новий потік в сервісі, щоб виконати цю роботу.
Хосе Хуан Санчес

8
"Служба IntentService повинна бути запущена з головної нитки." Ти впевнений? Всередині моєї програми MainActivity onCreate (), коли я закликаю IntentService з нової теми (код нижче), вона все ще працює для мене. new Thread (new Runnable () {@Override public void run () {Intent intennt = new Intent (контекст, HelloIntentService.class); startService (наміри);}}). start ();
Ashok Bijoy Debnath

9
@AshokBijoyDebnath Ви праві! У послугах і IntentServices можуть бути запущені з будь-якого потоку, активності або іншого компонента програми. Я щойно відредагував текст відповіді, щоб виправити це питання. Дякуємо за пропозицію щодо редагування! :)
Жозе Хуан Санчес

2
Немає проблем, іди за цим!
Хосе Хуан Санчес

165

Якщо хтось може показати мені приклад того, що можна зробити за допомогою, IntentServiceа не можна зробити з a Serviceі навпаки.

За визначенням, це неможливо. IntentServiceце підклас Service, написаний на Java. Отже, все IntentService, що Serviceможна, може зробити, включивши відповідні біти коду, який IntentServiceвикористовує.

Розпочати послугу власним потоком - це як запустити IntentService. Чи не так?

Три основні ознаки IntentService:

  • фонова нитка

  • автоматична черга з Intents доставляється до onStartCommand(), тому якщо один Intentобробляється onHandleIntent()у фоновому потоці, інші команди стоять у черзі в очікуванні своєї черги

  • автоматичне відключення IntentServiceчерез виклик до stopSelf(), коли черга буде порожньою

Будь-яке і все це можна реалізувати Serviceбез розширення IntentService.


6
Трохи пізно, але я знаходжу , що Serviceназивається з startServiceможе працювати тільки в протягом приблизно 10 секунд , перш ніж кидати ANR-- IntentServiceпочав з мовленням наміру , здається, не має це обмеження
edthethird

16
@edthethird: Це тому, що ви зав'язували основний потік програми. Усі методи життєвого циклу для всіх компонентів, включаючи onStartCommand()a Service, викликаються в основному потоці програми. Ви не можете зв’язати цей потік більше декількох мілісекунд, не заморозивши інтерфейс користувача, і якщо вам знадобиться багато секунд, ви отримаєте службовий еквівалент ANR.
CommonsWare

3
так я коментував занадто рано. Я робив роботу onStartCommandзамість onHandleIntent- схоже, onStartCommandце запускається на потоці інтерфейсу, однак окремий потік створюється для onHandleIntentвиконання.
edthethird

3
@IgorGanapolsky: IntentServiceдзвонить, що сам, після onHandleIntent()повернення, якщо більше не буде роботи.
CommonsWare

1
Питання - не англійська, а програмування. Наприклад, "я закрив додаток" не має точного визначення, тому я не можу сказати вам, що відбувається, коли це відбувається. Я також не знаю, як "я закрив додаток" стосується "завантажуватимуться через 1 годину". Ви можете задати окреме запитання щодо переповнення стека, де ви можете навести мінімальний відтворюваний приклад "завантажуватимуться через 1 годину". Там ви можете детально пояснити, що означає "я закрив додаток" (наприклад, що конкретно робить користувач, щоб закрити додаток?).
CommonsWare

39

Сервіс

  • Викликати startService()
  • Запускається від будь-якого Thread
  • Біжить далі Main Thread
  • Може блокувати основний потік (UI). Завжди використовуйте нитку в сервісі для тривалого завдання
  • Після того, як завдання виконано, наша відповідальність припиняє обслуговування за телефоном stopSelf()абоstopService()

IntentService

  • Він виконує довге завдання, як правило, не має зв'язку з основною потоком, якщо комунікація потрібна, то це виконується HandlerабоBroadcastReceiver
  • Викликати через Intent
  • Запущено с Main Thread
  • Працює на окремій нитці
  • Неможливо виконати завдання паралельно, і декілька намірів стоять у черзі на одній робочій нитці.

19

Не винаходити колесо

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

То яка мета?

`Метою IntentService є полегшити нашу роботу для виконання фонових завдань, навіть не турбуючись про це

  • Створення робочої нитки

  • Черга на обробку декількох запитів по одному ( Threading)

  • Знищення Service

Так НІ , Serviceможна виконати будь-яке завдання, яке IntentServiceб зробив. Якщо ваші вимоги підпадають під вищезазначені критерії, вам не доведеться записувати ці логіки у Serviceкласі. Тому не винаходити колесо, тому що IntentServiceце придумане колесо.

Різниця "Головна"

Служба працює на потоці інтерфейсу користувача, тоді як IntentService працює на окремому потоці

Коли ви використовуєте IntentService?

Коли ви хочете виконувати кілька основних фонових завдань, що існують поза сферою діяльності, то IntentServiceце ідеально.

Як IntentServiceзроблено зService

Нормальне обслуговування працює на UI Thread (будь-який тип Android компоненти працюють на UI потоці за замовчуванням , наприклад Activity, BroadcastReceiver, ContentProviderі Service). Якщо вам доведеться виконати певну роботу, яка може зайняти деякий час, тоді вам доведеться створити нитку. У випадку кількох запитів вам доведеться розібратися synchronization. IntentServiceнадається деяка реалізація за замовчуванням, яка виконує ці завдання для вас.
За даними сторінки розробника

  1. IntentService створює робочу нитку

  2. IntentServiceстворює Робочу чергу, яка надсилає запит onHandleIntent()методу по одному

  3. Коли немає роботи, тоді IntentServiceвикликає stopSelf()метод
  4. Забезпечує реалізацію за замовчуванням для onBind()методу, який є нульовим
  5. Реалізація за замовчуванням, для onStartCommand()якої надсилає Intentзапит до WorkQueue і, нарешті, доonHandleIntent()

15

Додавання балів до прийнятої відповіді:

Дивіться про використання IntentService в Android API. наприклад:

public class SimpleWakefulService extends IntentService {
    public SimpleWakefulService() {
        super("SimpleWakefulService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {  ...}

Щоб створити компонент IntentService для вашої програми, визначте клас, який розширює IntentService, і всередині нього визначте метод, який перекриває onHandleIntent ().

Також дивіться вихідний код IntentService, це конструктор та методи життєвого циклу, як OnStartCommand ...

  @Override
    public int More ...onStartCommand(Intent intent, int flags, int startId) {
       onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

Спільне обслуговування AsyncTask - це один із найкращих підходів для багатьох випадків використання, коли корисна навантаження не величезна. або просто створити клас, що розширює IntentSerivce. З версії Android 4.0 всі операції з мережею повинні знаходитись у фоновому режимі, інакше компіляція / складання програми не вдається. окремий потік від інтерфейсу користувача. Клас AsyncTask пропонує один з найпростіших способів зняти нове завдання з потоку інтерфейсу користувача. Більше обговорення цієї теми дивіться у публікації в блозі

з посібника для розробників Android :

IntentService - це базовий клас для Служб, які обробляють асинхронні запити (виражаються як Інтенти) на вимогу. Клієнти надсилають запити через дзвінки startService (Intent); служба запускається у міру необхідності, обробляє кожну Намір, у свою чергу, використовуючи робочу нитку, і зупиняється, коли вона закінчується без роботи.

Шаблон дизайну, який використовується в IntentService

: Цей шаблон "процесор черги робочої черги" зазвичай використовується для завантаження завдань з основного потоку програми. Клас IntentService існує для спрощення цієї моделі та піклування про механіку. Щоб використовувати його, розгорніть IntentService та вкажіть onHandleIntent (Намір). IntentService отримає Інтенти, запустить робочу нитку та припинить послугу у відповідних випадках.

Усі запити обробляються в одному робочому потоці - вони можуть зайняти стільки часу, скільки потрібно (і не перекриють основний цикл програми), але одночасно буде оброблено лише один запит.

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

У IntentService є кілька обмежень:

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

IntentService є кращим способом простих фонових операцій

**

Волейбольна бібліотека

Існує бібліотека під назвою волей-бібліотека для розробки додатків для андроїд-мереж . Вихідний код доступний для громадськості в GitHub.

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


1
Було б краще, якщо ви могли б дати коротку відповідь до точки.
eRaisedToX

12

Я впевнений, що ви можете знайти широкий перелік відмінностей, просто переглянувши щось таке, як "Android IntentService vs Service".

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

Деякі приклади (швидко складені) можуть бути;

IntentService: якщо ви хочете завантажити купу зображень на початку відкриття програми. Це разовий процес і може очистити себе, як тільки все буде завантажено.

Сервіс: Служба, яка постійно використовуватиметься для зв'язку між вашим додатком та зворотним зв'язком за допомогою дзвінків веб-API. Навіть якщо вона закінчена своїм поточним завданням, ви все ще хочете, щоб це було через декілька хвилин для більшого спілкування.


2
Я не знайшов жодного прикладу, який можна зробити з одним, а не з іншим. лише деякі пояснення, які мені не допомогли.
roiberg

1
Спробуйте цей сайт, він має багато хороших пояснень щодо основних концепцій Android із гідними прикладами vogella.com/articles/AndroidServices/article.html
Стефан де

4
Це ще один приклад "як користуватися". не тоді, коли спеціально користуються сервісом і коли intentservice. Надайте, будь ласка, теоретичний приклад, а не посилання на "як користуватися" чи будь-які інші подібності для цього методу. Я не прошу вас "працювати" для мене, поки я нічого не роблю, просто я вже бачив усі ці смаки і досі не впевнений.
Ройберг

5
це досить важлива різниця. Наприклад, якщо ви використовуєте сервіс для постійного зв'язку з сервером, ви не можете використовувати intentservice для цього, оскільки він припиняється відразу після того, як він закінчить усі свої завдання
pelotasplus

24
коли я google це, це приводить мене сюди. тепер я перебуваю в нескінченному циклі.
Лу Морда

12

IntentService

IntentServiceпрацює на власній нитці. Він зупинить себе, коли це буде зроблено. Більше люблять вогонь і забути. Подальші дзвінки будуть у черзі. Добре підходить для викликів у черзі. Ви також можете обертати кілька потоків всередині, IntentServiceякщо вам потрібно. Ви можете досягти цього, використовуючи ThreadPoolExecutor. Я говорю це тому, що багато людей запитували мене "навіщо використовувати, IntentServiceоскільки воно не підтримує паралельне виконання". IntentServiceце просто нитка. Ви можете робити все, що вам потрібно, навіть обертаючи кілька ниток. Єдине застереження - це IntentServiceзакінчення, як тільки ви закручуєте ці кілька ниток. Він не чекає повернення цих тем. Вам потрібно подбати про це. Тому я рекомендую використовувати ThreadPoolExecutorв цих сценаріях.

  • Добре для синхронізації, завантаження тощо ...

Сервіс

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

  • Знову ви можете запустити кілька потоків, якщо вам потрібно.
  • Можна використовувати для таких додатків, як музичні плеєри.

Ви завжди можете спілкуватися про свою діяльність, використовуючи, BroadcastReceiversякщо вам потрібно.


8

IntentService - це розширення Служби, яке робиться для полегшення виконання завдання, яке потрібно виконати у фоновому режимі та в окремій потоці.

IntentService запускає, створює потік і виконує своє завдання в потоці. як тільки зроблено, воно все очищає. Одночасно може запускатись лише один екземпляр IntentService, запускається кілька дзвінків.

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

Наприклад, сервіс, підключений до сервера xmpp та пов'язаний з діяльністю, не може бути просто виконаний за допомогою IntentService. Ви ігноруєте або переосмислюєте вміст IntentService.


Що здається, що більшість людей, які хочуть запустити справжню тривалу службу у фоновому режимі, намагаються дізнатися про IntentService, тому що в документах це здається, що це робиться для цього, але в основному ти можеш так само добре використовувати нову тему (новий Runnable ()). start (). Іншими словами, коли він говорить про "породить нову нитку", що це все, що вона робить, він не переміщує її до окремого процесу, який насправді те, що більшість людей хоче зробити, коли вони хочуть відокремити деякий запущений код від діяльності (тому що лише нерестові нитки - це один вкладиш)
Lassi Kinnunen,

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

5

Якщо хтось може показати мені приклад чогось, що ви можете зробити з IntentServiceі не можна зробити з a serviceі навпаки.

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

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


4

Основна різниця між a Serviceі an IntentServiceописується так:

Сервіс:

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

2. Дозволяє одночасно кілька запитів (Multi Threading)

IntentService:

1.Зараз, IntentServiceсюди, тут доступна робоча нитка за замовчуванням для виконання будь-якої операції. Зауважте, що вам потрібно реалізуватиonHandleIntent() метод, який отримує наміри для кожного запиту запуску, де ви можете виконувати фонову роботу.

2.Але це дозволяє одночасно лише один запит.


3

Android IntentService vs Service

1.Сервіс

  • Служба викликається за допомогою startService ().
  • Службу можна викликати з будь-якого потоку.
  • Сервіс за замовчуванням виконує фонові операції на головній нитці програми. Отже, він може блокувати інтерфейс програми.
  • Служба, яку викликали кілька разів, створила б кілька примірників.
  • Службу потрібно зупинити, використовуючи stopSelf () або stopService ().
  • Служба Android може виконувати паралельні операції.

2. Служба Намір

  • Служба IntentService викликається за допомогою Intent.
  • Служба IntentService може використовувати лише основний потік.
  • IntentService створює окремий робочий потік для запуску фонових операцій.
  • Служба IntentService, яку викликали кілька разів, не створюватиме кілька примірників.
  • Сервіс IntentService автоматично зупиняється після завершення черги. Не потрібно запускати stopService () або stopSelf ().
  • У сервісі IntentService кілька чергових викликів автоматично збираються в чергу, і вони будуть виконуватися послідовно.
  • IntentService не може запускати паралельну операцію, як Сервіс.

Зверніться сюди

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