- PVSM.RU - https://www.pvsm.ru -
В этой статье мы поговорим о различных механизмах, посредством которых взаимодействуют части Android-приложений. Условимся называть все эти механизмы «уровнем взаимодействия» (насколько мне известно, в документации Android нет специального термина для этого).
Как было показано ранее, фреймворк Android реализует несколько шаблонов взаимодействия:
Очевидно, это первый механизм взаимодействия, с которым сталкивается разработчик, начав программировать под Android. Он используется для запуска активити [9] или сервиса [7]. Мехнанизм реализуется с помощью трёх методов класса Context [10] (о котором говорилось в одной из предыдущих статей [11]) и одного метода класса Activity:
В обоих случаях класс Intent выполняет роль передаваемого сообщения.
Как Android узнаёт, какому активити или сервису адресуется сообщение? Для этого есть два способа:
Имейте ввиду, что в случае отправки сообщения (экземпляра класса Intent) механизм взаимодействия доставит его только одному компоненту, или не доставит вовсе.
Механизм взаимодействия издатель/подписчик использует тот же класс Intent в качестве сообщения и те же фильтры, что и механизм определения целевого компонента, но работает несколько иначе. Интенты, используемые в данном случае, называются «широковещательными». Эти интенты могут быть доставлены только BroadcastReceiver'у.
В отличие от интентов, используемых для отправки сообщений, один широковещательный интент может быть доставлен нескольким компонентам.
Фактически, Android реализует два разных механизма издатель/подписчик, каждый из которых имеет по две версии (обычную и «липкую», «sticky»):
Я же ещё не сбил вас с толку, так?
Нормальный механизм вещания доставляет интент до всех подходящих броадкаст-ресиверов асинхронно, и они реагируют на них независимо. То есть одни броадкаст-ресивер не может влиять на то, как другой броадкаст-ресивер реагирует на интент, или как интент доставляется другому броадкаст-ресиверу. Это обычный шаблон издатель/подписчик.
Упорядоченный механизм вещания доставляет интенты до всех подходящих броадкаст-ресиверов последовательно, то есть только одному за раз. Поэтому каждый броадкаст-ресивер потенциально может:
Компоненты, инициализировавшие упорядоченное вещание, получают возможность принимать результат обработки интента от всей цепи броадкаст-ресиверов.
Упорядоченное вещание является реализацией шаблона цепочка обязанностей [13].
«Липкое» вещание — разновидность обычного вещания. Разница в том, что интент доступен до тех пор, пока он не будет явно удалён методом removeStickyBroadcast() класса контекст. Помните, что этот тип вещания следует использовать с осторожностью, поскольку не удалённые «липкие» интенты приводят, в итоге, к утечке памяти.
Все описанные механизмы взаимодействия используют класс Intent в качестве сообщения. Обратите внимание, большая часть представленных методов реализована классом Context, а это значит, что теоретически они могут быть использованы всеми его подклассами.
Отсюда можно сделать вывод, что все механизмы взаимодействия Android используют класс Intent. Но это не совсем так.
В большинстве случаев класс ContentProvider [6] используется как обёртка вокруг базы данных SQLite. Хотя, теоретически, он может быть использован для других механизмов храненияполучения данных. Об использовании этого класса можно почитать здесь [14].
Существует множество способов использования контент-порвайдеров. Одни включают получение объектов, которые работают как прокси над контент-порвайдером (обычно это экземпляр или подкласс ContentProviderClient [15], который реализует шаблон прокси [16]). Другие возвращают экземпляр класса Cursor [17], который позволяет перебирать множество данных, возвращённых конетнт-провайдером. В любом случае, конкретный ContentProvider должен идентифицироваться по URI (подробнее см. тут [14]).
В любом случае, это типичный шаблон позднее связывание [5].
Если вы думаете, что на этом механизмы взаимодействия закончились, то вы ошибаетесь.
В стороне от класса ContentProvider находится класс Service, который выполняет роль модели в архитектуре MVVM. В предудущей статье [18] мы обсуждали гипотетические причины, по которым Android имеет два разных класса, выполняющих одну и ту же роль.
Немного сбивает с толку то, что один и тот же сервис может быть использован и как локальный, и как удалённый; разница в том, где расположены компоненты, взывающие сервис (в том же процессе или в другом).
Здесь [20] и здесь [7] можно прочесть подробнее об использовании сервисов.
Предыдущие статьи:
От переводчика. Это последняя из четырёх статей Влада Невзорова [23] об архитектуре Android-приложений. Мне бы хотелось выразить свою благодарность любимой супруге Гале за помощь и за то, что не отвлекала меня от компьютера несколько вечеров, а так же читателям Monnoroch [24], Semp [25], PomanoB [26], ssidelnikov [27], So1 [28], Manul [29], pravic [30] и szKarlen [31] за дельные комментарии и замечания.
Автор: ilichme
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android/4902
Ссылки в тексте:
[1] Обмен сообщениями: http://en.wikipedia.org/wiki/Message_passing
[2] Intent: http://developer.android.com/reference/android/content/Intent.html
[3] Наблюдатель: http://en.wikipedia.org/wiki/Publish_subscribe
[4] BroadcastReceiver: http://developer.android.com/reference/android/content/BroadcastReceiver.html
[5] Позднее связывание: http://en.wikipedia.org/wiki/Late_binding
[6] ContentProviders: http://developer.android.com/reference/android/content/ContentProvider.html
[7] Services: http://developer.android.com/reference/android/app/Service.html
[8] Inter-process Procedure Communication: http://en.wikipedia.org/wiki/Inter-process_communication
[9] активити: http://developer.android.com/reference/android/app/Activity.html
[10] Context: http://developer.android.com/reference/android/content/Context.html
[11] статей: http://wp.me/p1gzYo-3P
[12] фильтрах интентов: http://developer.android.com/guide/topics/intents/intents-filters.html
[13] шаблона цепочка обязанностей: http://en.wikipedia.org/wiki/Chain_of_responsibility_pattern
[14] здесь: http://developer.android.com/guide/topics/providers/content-providers.html
[15] ContentProviderClient: http://developer.android.com/reference/android/content/ContentProviderClient.html
[16] шаблон прокси: http://en.wikipedia.org/wiki/Proxy_pattern
[17] Cursor: http://developer.android.com/reference/android/database/Cursor.html
[18] предудущей статье: http://habrahabr.ru/post/141201/
[19] AIDL: http://developer.android.com/guide/developing/tools/aidl.html
[20] Здесь: http://developer.android.com/guide/topics/fundamentals/services.html
[21] Архитектура Android-приложений. Часть I — истоки: http://habrahabr.ru/post/140459/
[22] Архитектура Android-приложений. Часть II — архитектурные стили и шаблоны: http://habrahabr.ru/post/140655/
[23] Влада Невзорова: http://vladnevzorov.com
[24] Monnoroch: http://habrahabr.ru/users/monnoroch/
[25] Semp: http://habrahabr.ru/users/semp/
[26] PomanoB: http://habrahabr.ru/users/pomanob/
[27] ssidelnikov: http://habrahabr.ru/users/ssidelnikov/
[28] So1: http://habrahabr.ru/users/so1/
[29] Manul: http://habrahabr.ru/users/manul/
[30] pravic: http://habrahabr.ru/users/pravic/
[31] szKarlen: http://habrahabr.ru/users/szkarlen/
Нажмите здесь для печати.