Почему я не должен использовать шину сообщений вместо Loaders and Services?

В типичном Android-проекте, где нам нужно как-то извлекать данные из (REST, SQL, cache и т.д.) В пользовательский интерфейс, мы обычно используем Loader, Service или (возможно, yuk) AsyncTask, но я нахожу все эти подходы неудовлетворительно по нескольким причинам:

  • Они уродливые, особенно Loaders, у которых ужасная структура API
  • Это слишком просто, чтобы обернуться в потоки и наступить на поток пользовательского интерфейса
  • Наш код уровня презентации загрязняется кодом Android и шаблоном. Мы часто передаем объекты Android (например, курсоры) прямо на уровень пользовательского интерфейса, что делает невозможным достижение чистой архитектуры. Это заставляет нас смешивать специфический код бизнес-домена (в идеале простые объекты Java) с кодом платформы Android - не очень подходит для читаемости, обслуживания, тестирования или гибкости для будущей разработки. На практике мы часто получаем огромные, грязные классы Activity/Fragment.

Меня привлекают такие идеи, как те, которые описаны в этих статьях: http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/ http://antonioleiva.com/mvp-android/ http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html

Успешно приступив к использованию MVP, чтобы разбить "Действия/Фрагменты/Представления" на части меньшего размера/чистого, я теперь думаю, что решение вышеперечисленных проблем может заключаться в том, чтобы полагаться на шину сообщений (Otto, EventBus и т.д.) Вместо служб или загрузчики или что-либо другое для взаимодействия с данными домена.

Поэтому на практике это означало бы вместо использования (например) CursorLoader для загрузки курсора из базы данных, вместо этого я бы использовал шину сообщений для отправки сообщения для запроса данных, данные загружаются в фоновый поток в ответ на это сообщение, а затем обрабатывать данные ответа, когда он поступает через сообщение в потоке пользовательского интерфейса. Для меня очень важно, чтобы структура данных была исключена из бизнес-домена, а не из домена Android, поэтому я предпочел бы массив бизнес-объектов для курсора.

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

  • Может быть сложнее (особенно для новых разработчиков) понять код
  • Необходимо будет обеспечить отправку и получение сообщений по нужным потокам (похоже, у Отто есть ограничения)
  • Необходимо будет избежать соблазна реализовать все как сообщение, которое в конечном итоге будет контрпродуктивным
  • Передача коллекций бизнес-объектов вокруг может быть менее эффективной, чем использование объектов, таких как курсоры. Хотя во многих сценариях это проблема на практике?
  • Я не знаю, предназначены ли Otto/EventBus только для передачи очень маленьких сообщений или целесообразно передавать более крупные объекты (например, массив бизнес-объектов).

Мой вопрос в том, есть ли какие-либо основополагающие причины, чтобы не использовать этот подход, основанный на сообщениях, с приложениями для Android?

Ответы

Ответ 2

любые основополагающие причины НЕ принимать этот подход, основанный на сообщениях, с приложениями для Android

Нет, я думаю. В моей практике я работал со "запасными" вещами, такими как Loaders и AsyncTasks (я бы не стал использовать Службы в этой строке, потому что его ответственность намного шире). Затем была реализована функция автобуса, и угадайте, что? Жизнь стала легче и более предсказуемой, развязка увеличилась. Когда я полностью переехал в Rx, работа стала не только проще, но и смешнее! Однако ничто не спасет вас от работы с жизненными циклами.

Все это только детали реализации, более важно, чтобы глобальные вещи были ясны. Когда вы говорите о чистой архитектуре, нужно скрыться от уровня пользовательского интерфейса (Activities, Fragments, Views...), как и где объекты появляются. После того, как вы инкапсулируете эту определенную работу в usecases, неважно, какой инструмент использовать: загрузчики, шины или Rx - ваш уровень пользовательского интерфейса должен придерживаться только интерфейса, предоставляемого usecase - обратных вызовов, событий или наблюдаемых

Я бы указал на две вещи:

  1. Чем меньше уровень знаний о внедрении usecase, тем лучше.
  2. Если вы выбрали один конкретный инструмент для реализации, используйте его везде. Не смешивайте несколько инструментов для одной и той же работы.

Ответ 3

Несколько лет назад не было сильных устройств для Android, которые имеют 3 ГБ бара или больше. Когда у вас есть сетевой вызов из вашего приложения, и ваше приложение получает прерывание, например, вы получаете телефонный звонок и отправляете свое приложение в фоновом режиме (если вы не пользуетесь услугой), ваше приложение будет убито и вы будете тратить свой сетевой вызов. Если у вас есть работающий сервис, связанный с вашим приложением, ваше приложение получит низкий приоритет, чтобы его убили ОС Android

Также с помощью сервисов вы можете сделать ваши работы не-ui или длинные живые процессы, отделенные от ui-thread. Это хороший подход для приложения non-blocking-ui. Также вы можете обрабатывать изменения ориентации.

В настоящее время, как вы говорите, в Android Dev есть другие варианты (библиотеки, шаблоны и т.д.). мире, таком как MVP, MVC, MVVM, Retrofit, OttoBus...

Я думаю, что нет определенного правильного пути для разработки вашего Android-приложения, такого как "вам нужно использовать MVP, Retrofit, services, loaders, MVVM, Data Binding и т.д."

Но пока вы разрабатываете приложение для Android, вы можете рассмотреть эти принципы, и вы можете сделать свой выбор шаблонов и библиотек в соответствии с этими принципами. (Порядок принципов может быть изменен в соответствии с вашим проектом, временем, ресурсами и т.д.)

1- Clean code
2- Seperate layers
3- Non Blocking Ui
4- Don't waste user resources. (Avoid unneccassry network calls, memory allocation etc.)
5- Support orientation change.
6- Testing 
7- Clean Ui Design (Material Design)

Это старое видео, но каждый Android-разработчик должен смотреть его: https://www.youtube.com/watch?v=xHXn3Kg2IQE