Android: AsyncTask против службы

139

Почему я много читаю в ответах на большинство вопросов о AsyncTaskзагрузчиках и ничего не об услугах ? Службы просто не очень хорошо известны, или они устарели, или имеют какие-то плохие атрибуты или что-то в этом роде? Какие отличия?

(Между прочим, я знаю, что есть и другие темы по этому поводу, но ни один из них не указывает четких различий, которые помогают разработчику легко решить, лучше ли ему использовать тот или другой для реальной проблемы.

erikbwork
источник

Ответы:

274

В некоторых случаях можно выполнить одну и ту же задачу с помощью либо, AsyncTaskлибо, Serviceно обычно один лучше подходит для задачи, чем другой.

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

Services предназначены для непрерывной работы в фоновом режиме. В приведенном выше примере выборки данных при нажатии кнопки вы можете запустить службу, позволить ей получить данные, а затем остановить ее, но это неэффективно. Гораздо быстрее использовать AsyncTaskтот, который запустится один раз, вернет данные и все будет готово.

Однако, если вам нужно постоянно что-то делать в фоновом режиме, Serviceлучше всего использовать a . Примеры этого включают воспроизведение музыки, постоянную проверку наличия новых данных и т. Д.

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

По большей части Services используются, когда вы хотите запустить код, даже когда ваше приложение Activityне открыто. AsyncTasks предназначены для невероятно простого выполнения кода из потока пользовательского интерфейса.

Компьютерный
источник
2
Интересно, что в этом выступлении от Google I / O в 2010 youtube.com/watch?v=xHXn3Kg2IQE докладчик дает 3 различных метода получения данных из REST API, и первый использует сервис. Я не эксперт по Android, но у меня также сложилось впечатление, что то, что сказал Computerish, в основном правильно.
wuliwong
10
Последний абзац: «Службы предназначены для случаев, когда вы хотите запускать код, даже когда Activity вашего приложения не открыто». Это также относится к AsyncTask или фоновым потокам. то есть, когда вы нажимаете назад в своей активности или вызываете finish (), и ваша активность не отображается, но все же ваши фоновые потоки выполняются до тех пор, пока вы не завершите процесс своего приложения (например, путем переключения из недавних задач). Я проверил это с помощью 4.4.2 Google Nexus AOSP
grouper
10
Однако AsyncTask может быть сложным, если запущенное Activity было убито, пока AsyncTask все еще работает, и ему необходимо обновить пользовательский интерфейс после его завершения ... (что не сработает, поскольку Activity уже уничтожено). Почему бы не использовать IntentService, который, кстати, не нужно останавливать вручную, поскольку он просто завершается после завершения?
AgentKnopf
отличные моменты. хорошее объяснение службы. Это служба, работающая в фоновом режиме непрерывно, даже если работа выполнена.
BABU K
3
@LarsH Исправьте меня, если я ошибаюсь, но я думаю, вы могли бы использовать BroadcastReceiver в своей Activity / Fragment, а из IntentService вы просто запускаете Broadcast, как только закончите. Поскольку вы можете повторно зарегистрироваться для широковещательных рассылок после воссоздания активности / фрагмента, это должно вас охватить. Другой альтернативой было бы использование EventBus для обновления пользовательского интерфейса (хотя я стараюсь этого избегать - это затрудняет отслеживание кода imo).
AgentKnopf
57

Сервисы совершенно разные: Сервисы - это не потоки !

Ваше действие привязывается к службе, и служба содержит некоторые функции, которые при вызове блокируют вызывающий поток. Ваш сервис может быть использован для изменения температуры с Цельсия на Градусы. Любое связывающее действие может получить эту услугу.


Однако AsyncTaskэто поток, который выполняет некоторую работу в фоновом режиме и в то же время имеет возможность сообщать результаты обратно вызывающему потоку.

Подумать только: услуга может иметь AsyncTaskобъект!

Шериф Эль-Хатиб
источник
2
Службы описываются как работающие в фоновом режиме, но продолжают работать, даже когда приложение ur закрыто. AsyncTask также используется для выполнения каких-либо действий в фоновом режиме. Знаешь что я имею ввиду?
erikbwork 05
1
да, но сервисы могут что-то делать, а могут и не делать. Они - долговечный ОБЪЕКТ
Шериф эль-Хатиб
"У службы может быть объект AsyncTask!" Спасибо что подметил это. Но разве это хорошая идея - вы бы ее порекомендовали? Или было бы лучше использовать в сервисе более простые методы многопоточности?
RenniePet
«Ваша активность привязана к услуге» не обязательно.
JacksOnF1re,
@ JacksOnF1re Я знаю, что это похоже на то, как я только начинал писать код: p, но «Ваша активность привязана к службе» - верное утверждение. Я также мог быть привязан к этой службе. Холодильник тоже может быть обязательным. Это не делает заявление недействительным ... в любом случае, jk
Шериф эль-Хатиб
7

Serviceявляется одним из компонентов платформы Android, для выполнения которого не требуется пользовательский интерфейс, что означает, что даже когда приложение активно не используется пользователем, вы можете выполнять некоторые операции со службой. Это не означает, что служба будет работать в отдельном потоке, но она выполняется в основном потоке, и при необходимости операция может выполняться в отдельном потоке. Примеры использования: воспроизведение музыки в фоновом режиме, синхронизация данных с сервером в фоновом режиме без взаимодействия с пользователем и т. Д.

AsyncTaskс другой стороны, используется для выполнения задач блокировки пользовательского интерфейса в отдельном потоке. Это похоже на создание нового потока и выполнение задачи, когда все задачи по созданию и обслуживанию потоков и отправке результата в основной поток выполняются с помощью использования AsyncTask. Пример: выборка данных с сервера, операции CRUD на преобразователе контента и т. Д.

Арджун
источник
Можете ли вы указать, почему вы думаете, что ваш ответ что-то добавляет к вопросу?
erikbwork
2
другие ответы либо слишком короткие, либо слишком длинные для понимания новичками. поэтому я ответил точно простыми словами с примерами
arjun
6

Служба и асинтаксические задачи делают почти одно и то же, почти. Использование службы или асинтаксической задачи зависит от ваших требований.

в качестве примера, если вы хотите загрузить данные в список с сервера после нажатия какой-либо кнопки или изменения экрана, вам лучше использовать asynctask. он работает параллельно с основным потоком пользовательского интерфейса (выполняется в фоновом режиме). для запуска активности asynctack, или ваше приложение должно в основном потоке пользовательского интерфейса. после выхода из приложения нет асинтаксиса.

Но службы не такие, как только вы запустите службу, она может работать после выхода из приложения, если вы не остановите службу. Как я сказал, это зависит от ваших требований. Если вы хотите продолжать проверять получение данных или проверять состояние сети постоянно вам лучше идти со службой.

счастливого кодирования.

Ашана.Джаколь
источник
1
Привет, Ашана, могу я спросить, почему вы дали такой ответ на вопрос, на который уже дан ответ? Вас не устраивает уже отмеченный ответ? Или вы пытаетесь создать профиль SO, написав свое мнение на все вопросы, о которых вам есть что сказать? Или что-то совсем другое? Не могу понять, но в последнее время я довольно часто вижу такую ​​закономерность.
erikbwork
3
Я знаю, что ответ уже дан, и я не вижу здесь особых проблем, если я дам правильный ответ или свое мнение здесь, братан? потому что вы не единственный, кто ищет ответ на тот же вопрос, если кому-то сложно понять решение в приведенных выше ответах, он / она может прокрутить вниз, чтобы найти ответ, который хорошо подходит для них, легко понять его. Спасибо за комментарий, братан, я не гений и не профессионал в программировании, просто хочу помочь другим, попытаться научить других тому, что я уже знаю :)
Ashana.Jackol
1

В некоторых случаях вы можете достичь той же функциональности, используя оба. В отличие от асинхронной задачи, служба имеет собственный жизненный цикл и наследует контекст (служба более надежна, чем асинхронная задача). Сервис может работать, даже если вы вышли из приложения. Если вы хотите что-то сделать даже после закрытия приложения, а также вам нужна переменная контекста, вы выберете Service.

Пример: если вы хотите воспроизвести музыку и не хотите останавливаться, если пользователь покидает приложение, вы обязательно перейдете на Сервис.

Сайем Сиам
источник
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, вы можете это сделать. Например, вы можете запустить фоновый поток / AsyncTaskin Service.onCreate(). Но не для всех случаев использования это требуется. Например:

  • Возможно, вы захотите продолжить Serviceработу, чтобы продолжать получать обновления местоположения в «фоновом режиме» (то есть, не обязательно на Activitiesэкране).
  • Или вы можете захотеть сохранить свое приложение в рабочем состоянии, чтобы вы могли поддерживать «неявную» BroadcastReceiverрегистрацию на долгосрочной основе (после API 26 вы не всегда можете делать это через манифест, поэтому вам нужно зарегистрироваться во время выполнения). [ ref ]).

Ни один из этих вариантов использования не требует большой загрузки процессора; они просто требуют, чтобы приложение не было убито .

Как рабочие

Servicesне ориентированы на задачу. Они не настроены «выполнять задачу» и «приносить результат», как AsyncTasksони. Servicesне решают никаких проблем безопасности потоков (несмотря на то, что все методы выполняются в одном потоке). AsyncTasks, с другой стороны, справитесь с этой сложностью за вас.

Обратите внимание, что AsyncTaskэта функция устарела . Но это не означает , что вам следует заменить ваши AsyncTasksс Services! (Если вы что-то узнали из этого ответа, это должно быть ясно.)

TL; DR

Servicesв основном существуют, чтобы «существовать». Они похожи на заклинание Activity, заставляя приложение оставаться в живых, в то время как другие компоненты делают «работу». AsyncTasks«работают», но сами по себе они не будут поддерживать процесс.

greeble31
источник