Запуск службы android с использованием явного или неявного намерения

В соответствии со стандартной документацией на Android предпочтительным способом запуска службы (запущенной службы) является использование явного намерения, подобного этому:

// Using explicit intent:
Intent serviceIntent = new Intent(getApplicationContext(), MyService.class);
// or:
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);

Вы также можете запустить/остановить службу, используя неявное намерение с строкой действия, указанной в манифесте, например:

// Using implicit intent:
static final String serviceAction = "com.example.my.app.services.MYSERVICE";
Intent serviceIntent = new Intent(serviceAction);
startService(serviceIntent);

// AndroidManifest.xml:
<service android:name="com.example.my.app.services.MyService"
   android:exported="false" android:process=":services" >
   <intent-filter>
      <!-- Start/Stop service -->
      <action android:name="com.example.my.app.services.MYSERVICE" />
   </intent-filter>
</service>

Когда служба используется только локально (сторонние приложения не могут запускаться или привязаны к ней), в документации говорится, что вы не должны включать фильтр намерений в манифесте service, и вы должны установить тег экспортированный в значение false.

Примечание: действия и службы выполняются в отдельных процессах (: приложения и: процессы служб). Связь между активностью и сервисом осуществляется путем реализации интерфейсов AIDL (это делается потому, что только удаленное взаимодействие AIDL позволяет мне выполнять многопоточность в службе, которая должна обрабатывать IPC одновременно, причем не только между действиями, но главным образом между службами, запущенными внутри: услуг).

Мои вопросы:

Q1: Когда действия и службы, которые я использую в своем приложении, запускаются в двух разных процессах, мне нужно использовать неявные намерения по явным намерениям для запуска и остановки служб?

Q2: Когда процесс приложения завершен (уничтожен, а не в памяти), а процесс: службы запущен в фоновом режиме, как мне снова подключиться из нового процесса приложения к уже запущенному: сервису? Как-то мне нужно снова обратиться к процессу: services, чтобы я мог остановить запущенную службу внутри этого процесса. Это невозможно сделать с помощью AIDL afaik.

Проблема заключается в том, что Android может и может легко уничтожить процесс приложения: когда из-за ресурсов, и это нормально для меня, пока процесс: services продолжает работать. (Да, я знаю о влиянии на процесс, установив службу как службу переднего плана и т.д. Я тоже могу прочитать руководства;) но это не моя проблема).

Я не могу найти какую-либо информацию или ответы, связанные с моими вопросами, когда действия и службы находятся в разделенных процессах и используют AIDL, а когда: процесс приложения должен "найти" процесс: services снова после его смерти Android или когда пользователь снова заходит в приложение (после того, как он/она оставил приложение раньше).

Любые консультации на уровне экспертов приветствуются.

Ответ 1

A1: Несмотря на то, что ваша деятельность и служба работают в разных процессах, они все равно принадлежат одному приложению. Вы все еще можете использовать явное намерение, я не вижу особого преимущества использования неявного намерения здесь (дайте мне знать, если найдете какое-либо :))

A2: позвольте мне перечислить несколько фактов здесь

  • Жизненный цикл службы "Запущено" (а не службы "Связать") не зависит от жизненного цикла Активности, которая запустила эту службу. Это верно независимо от того, работают ли оба в одном и том же процессе или нет.
  • Только один экземпляр Сервиса будет жив в любой момент времени. когда ваша деятельность вызывает startService(), экземпляр службы будет создан, если он еще не запущен (в этом случае ваша служба также получит обратный вызов onCreate()). Но если Service уже запущен, Framework просто вызовет обратный вызов onStartCommand() для уже запущенного процесса (в этом случае обратного вызова нет onCreate()). Опять же, все это верно, независимо от активности, и служба работает на одном и том же процессе или разных процессах.

Теперь, чтобы ответить на ваш вопрос, если ваша служба все еще работает (из-за вызова startService() предыдущим действием), тогда bindService()/startService() обязательно подключится к существующей службе.

Надеюсь, это поможет вам. Дайте мне знать, если у вас есть другие конкретные вопросы.

Ответ 2

Вам не нужно использовать неявное намерение начать сервис или деятельность в отдельном процессе; однако использование отдельного процесса для Activity является редким сценарием. Использование отдельного процесса для Сервиса является более распространенным явлением, но тем не менее я хотел бы знать, что такое вариант использования.

Если ваш процесс приложения уничтожен и затем перезагружен, вы должны использовать startService для повторного подключения к Сервису. Если служба запущена, вы подключаетесь к ней, иначе служба перезапускается. Если вы хотите убить Сервис, вы можете его убить, или вы можете запустить stopService() из основного приложения.

Что делает сервис?