Android: несколько сервисов намерений или один сервис намерений с несколькими намерениями?

Я немного запутался в намеренииService. В документах говорится, что если вы отправляете несколько задач (намерений) в службу намерений, то они будут выполняться одна за другой в одном отдельном потоке. Мой вопрос: возможно ли одновременное использование нескольких потоков IntentService или нет? Как вы различаете в коде создание трех разных намерений в одном и том же намерении (один и тот же поток) или трех отдельных намерений, каждый со своим собственным потоком и одним намерением для каждого?

Другими словами, когда вы выполняете команду startService(intent), вы помещаете намерение в одну очередь или каждый раз запускаете новую очередь?

Intent someIntent1 = new Intent(this, myIntentService.class);
Intent someIntent2 = new Intent(this, myIntentService.class);
Intent someIntent3 = new Intent(this, myIntentService.class);
startService(someIntent1);
startService(someIntent2);
startService(someIntent3);



Ответы (1)


1) Возможно ли одновременное наличие нескольких потоков IntentService или нет?

Нет, у каждого IntentService есть только один HandlerThread, который он использует для выполнения запросов в том порядке, в котором "startService " называется. Если только вы по какой-то причине не решите создать свой собственный поток/потоки в IntentService, но это, скорее всего, помешает использованию IntentService в первую очередь. Службы с одним и тем же объявлением манифеста, т. е. имя службы = ".MyIntentService" (и это то же самое для обычных служб), работают как синглтон в своем процессе, поэтому, пока служба не будет убита, одна и та же служба будет получать дополнительные запросы на запуск.

2) Как вы различаете в коде создание трех разных намерений для одного и того же IntentService?

Чтобы различать запросы, используйте систему Intent по назначению! Предоставьте разные «Действия» для разных заданий, которые может выполнять служба, и передайте любые дополнительные функции, необходимые IntentService для правильной работы для этого конкретного задания, в качестве дополнительных в объекте Intent, который вы используете для запуска службы.

person Submersed    schedule 13.06.2016
comment
Если я использую разные службы намерений, например: Intent someIntent1 = new Intent(this, myIntentService1.class); Намерение someIntent2 = новое намерение (это, myIntentService2.class); Намерение someIntent3 = новое намерение (это, myIntentService3.class); startService(someIntent1); startService(someIntent2); startService(someIntent3); они все еще работают в одном и том же handlerThread? - person Jon; 13.06.2016
comment
Да, все запросы к startService будут попадать в onHandleIntent() в том порядке, в котором startService вызывается с каждым объектом намерения. Итак, в основном вы ставите в очередь три задания для службы Intent для запуска в порядке очереди. Как только onHandleIntent() завершит выполнение/или будет заблокирован текущей операцией, он будет обработан следующим запросом startService(Intentintent), который вы поставили в очередь. Как только все задания startService будут завершены, служба намерений отключится, потому что у ее базового обработчика больше нет сообщений для обработки. - person Submersed; 13.06.2016
comment
@pskink, на самом деле это вопрос, потому что если три службы создают три потока, то на самом деле нет возможности ставить задачи в очередь в одном и том же handlerThread, и если это так, то я не понимаю, что имеют в виду документы разработчиков, когда они говорят об этой очереди. . - person Jon; 13.06.2016
comment
из документов: все запросы обрабатываются в одном рабочем потоке - они могут занимать столько времени, сколько необходимо (и не будут блокировать основной цикл приложения), но за раз будет обрабатываться только один запрос. - person Jon; 13.06.2016
comment
@Jon вызовите startService(someIntent1) дважды, вызовите startService(someIntent2) четыре раза и добавьте немного Log.d в каждый метод onHandleIntent, и вы увидите, как это работает. - person pskink; 13.06.2016
comment
Вы также можете посмотреть исходный код IntentService — на самом деле это довольно просто. Это просто требует некоторых знаний о том, как работает обработчик - они обслуживают только одно сообщение в своем потоке за раз. - person Submersed; 13.06.2016
comment
Да, я понимаю, что они обслуживают только одно сообщение за раз, просто я был сбит с толку, можно ли создавать несколько очередей сообщений одновременно или нет. - person Jon; 13.06.2016
comment
Единственный способ иметь несколько IntentServices (и это то же самое для обычных служб) — запускать их в отдельных процессах — нонсенс. - person CommonsWare; 13.06.2016
comment
@Jon: я был сбит с толку тем, можно ли одновременно создавать несколько очередей сообщений или нет - да. У каждого IntentService есть своя рабочая очередь. Ваша цитата из документов относится к одному IntentService, а не к трем отдельным IntentServices. - person CommonsWare; 13.06.2016
comment
@CommonsWare, как? Первый, если он уже создан в текущем приложении, будет получать дополнительные сообщения и работать в ранее созданном сервисе до тех пор, пока пул сообщений не будет исчерпан, а затем он будет закрыт (поэтому в ServiceHandler после onHandleIntent вызов stopService(int startId) вызывается вызов. В этот момент будет создан другой экземпляр. По крайней мере, так я понимаю, поэтому, если это отличается, что-то большее, чем ерунда, будет лучшим комментарием. - person Submersed; 13.06.2016
comment
@CommonsWare Вы имеете в виду, что возможно иметь несколько служб намерений в одном процессе, или что невозможно иметь несколько служб намерений, даже если вы используете разные процессы (т.е. одну единую очередь для всей системы)? - person Jon; 13.06.2016
comment
@ Джон, как я уже сказал, если у вас есть 3 отдельных IntentServices, то у вас есть 3 HandlerThreads, но что, если вы хотите запросить другой тип сообщения? Вы хотите добавить еще один IntentService? имхо смысла нет - person pskink; 13.06.2016
comment
@Submersed: как? -- создав более одного подкласса IntentService. Первый, если он уже создан в текущем процессе приложения, будет получать дополнительные сообщения — только для startService() вызовов с Intent, идентифицирующим этот IntentService. У каждого IntentService есть свой HandlerThread, у которого, в свою очередь, есть свой MessageQueue. В то время как отдельный класс Service фактически является одноэлементным, отдельные классы Service имеют независимые жизненные циклы, как и отдельные экземпляры Activity. И все они могут быть в одном процессе. - person CommonsWare; 13.06.2016
comment
Отредактировано для уточнения. Моя формулировка явно была ошибочной. - person Submersed; 13.06.2016
comment
@Jon: вы имеете в виду, что в одном процессе может быть несколько служб намерений - да, если они являются отдельными реализациями. В вашем вопросе вы запускаете одну и ту же службу (myIntentService) три раза. Это создаст один экземпляр службы, который последовательно обработает три поставленные в очередь команды. Если, OTOH, у вас есть три отдельных подкласса IntentService (например, myIntentService, myIntentService2, myIntentService3), и вы вызываете startService() один раз для каждого из них, они будут работать параллельно. - person CommonsWare; 13.06.2016
comment
@Submersed: я ожидаю какой-то ошибки сборки, если вы попытаетесь иметь более одного элемента <service>, указывающего на один и тот же компонент, даже если вы используете разные значения android:process. В конце концов, Android не может различить их, когда используется явное Intent. - person CommonsWare; 13.06.2016
comment
@CommonsWare Да, я тоже. Я еще больше упростил, так как эта часть на самом деле не была необходима, чтобы донести суть, просто тот факт, что Сервисы являются одиночными элементами в своем процессе - это все, что я пытался здесь сказать. Хотя сейчас мне интересно протестировать несколько вариантов использования :) - person Submersed; 13.06.2016