2015-01-09 2 views
3

Сценарий: У меня есть Controller (нормальный класс Java), который должен иметь возможность пилотировать несколько Slave.Почему AIDL/Messenger привязаны к службе?

Природная Slave «s может отличаться, так что это может быть:

  1. Service, давайте называть его ServiceSlave: жизненный цикл этого объекта, как правило, отличается от компонентов приложения (например, это делает не зависит от текущей активности)
  2. простого класса Java, скажем, ObjectSlave: жизненный цикл этого объекта несколько связанный с областью, в которой он был создан (скажем, текущая активность)

Что общего у этих двух типов: Slave s, то есть они могут находиться в разных процессах.


Из-за этого последнего «требование», я сразу обратил внимание на AIDL/Messenger как форма связи между Controller и Slave, так как она обеспечивает IPC.

Тем не менее, кажется, что AIDL (и, в свою очередь Messenger, так как она должна быть основана на AIDL а) только был определен, если вы хотите работать с Service. То есть, у меня нет возможности реализовать интерфейс на основе AIDL без объекта IBinder, который обычно предоставляется в методе onServiceConnected.

ПЕРВЫЙ ВОПРОС: может AIDL действительно можно использовать только при работе с Service? Если да, то почему?

Теперь рассмотрим мой сценарий. Я бы хотел, чтобы любой другой хороший разработчик написал один элегантный интерфейс, который позволяет Controller пилотировать каждый Slave, независимо от их характера. Единственное решение, которое дошло до меня до сих пор, связано с использованием Intent s и BroadcastReceiver s, все они удобно завернуты в выделенные классы Java.

ВТОРОЙ ВОПРОС: Это единственный жизнеспособный способ? Я что-то наблюдаю?


EDIT

Я предполагаю, что я должен дали более подробную информацию о том, что на самом деле делает Controller элемент. Это компонент, который слабо связан с несколькими виджетами пользовательского интерфейса, которые подписываются на него. Он был разработан (охотно), так что ему не нужна ссылка на Context. Так что это не необходимо или использовать UI виджеты напрямую, но в свою очередь эти виджеты зависят от Controller.

+0

ОК, с отредактированной информацией, я запутался о том, что реальной цели Парадигма Controller/Slave. Если он полностью является внутренним для «Активность» в вашем приложении (без необходимости использования «Контекста»), вы вообще не хотите «Сервис», AIDL или «Messenger». Все они используются, когда вы пересекаете границы процесса или ('Service'), что-то работает, не ориентированное на пользовательский интерфейс.Если вы просто используете это как внутреннюю систему типа публикации-подписки, тогда вам нужно будет определить классы и интерфейсы. При этом вы можете захотеть посмотреть EventBus или Otto как возможные сторонние помощники. –

+0

ОК, поэтому у меня явно есть проблемы с объяснением этого. Мой главный вопрос касается связи между «Контроллером» и «Ведомым», где последнее может быть или не быть «Сервисом». Коммуникация должна быть inter-process (поскольку «Controller» и «Slave» могут работать на разных процессах), но она также может быть внутри одного и того же процесса. – Sebastiano

+0

Но присутствует ли «Контроллер» только при запуске «Активность»? –

ответ

3

Это хороший, но не простой вопрос для ответа. Как и большинство вещей, существует множество подходов к решению этой проблемы. Первое, что нужно изучить, - это то, нужен или нет ваш Controller или использует компонент пользовательского интерфейса. Если нет, то вам необходимо инкапсулировать его в Service.Activity Жизненный цикл таков, что он будет работать только тогда, когда это текущая вещь на экране. Как только пользователь нажимает HOME или BACK, он либо останавливается, либо уничтожается соответственно. Запуск другого приложения через уведомление или из вашего приложения будет иметь эффект, похожий на нажатие HOME: ваш Activity будет приостановлен.

Таким образом, если вам не нужно/хотят UI для вашего Controller, у вас есть множество вещей в вашем распоряжении:

  1. сделать свой сервис «связанной» службой, подвергнув настраиваемый пользовательский интерфейс AIDL. Не сложно, но не для финта сердца.
  2. Сделайте свою услугу ответом на обычай Intent s, чтобы принять меры. Затем Service может отстреливать трансляции или запускать конкретный «ведомый» Activity. Если вы заинтересованы в этом, изучите использование IntentService, чтобы лучше управлять потоковой обработкой и предотвращать ANR вашего приложения.
  3. Как и предыдущий, используйте пользовательский Intent и отправьте свой подчиненный объект Messenger, который он создал в качестве дополнительного в пределах Intent. В этот момент Service может отправлять сообщения Messenger, который принадлежит ведомому Activity, и будет доставлен по определенному адресу Handler.

Вам не нужен пользовательский AIDL подвергается интерфейс для вариантов 2 и 3. Вы правы в том, что вы должны определить интерфейс AIDL, если вы собираетесь использовать связанную службу и ваш метод Service.onBind() должен возвращать экземпляр ваша реализация связующего интерфейса.

Все, что сказано, вы можете использовать любой из трех подходов для достижения своей цели работы с подчиненными классами, которые находятся либо в Activity, либо в Service экземплярах. Преимущество использования подходов AIDL или Messenger - это сокращение переключения контекста (более эффективное), поскольку вы не отправляете Intent объектов. Каждый раз, когда вы отправляете Intent, отправитель связывается с ActivityManagerService, работающим в системном процессе, для разрешения, где должно быть доставлено Intent. При использовании AIDL и Messenger только начальные вызовы bindService() или startService() обращаются к ActivityManagerService. После этой точки связь выполняется с использованием прямых связующих веществ между двумя процессами.

+0

Хорошая агрегировка! Можете ли вы указать собственные приложения с открытым исходным кодом, используя эти концепции? – Nova

2

Выбрано AIDL и Binder не привязаны к Service s.

Хотя это правда, что IBinder ссылка предоставляется только при привязке к Service, структура предлагает Binder класс, который уже реализует интерфейс IBinder.

Кроме того, экземпляр Binder работает прозрачно через процессы, и он не обязан жить в контексте Service.


[еще разработки, обеспечит схему, как структура может быть реализована непосредственно с использованием экземпляра Binder]

Смежные вопросы