Android developer design pattern

Архитектура Android-приложений. Часть II — архитектурные стили и шаблоны

В этой статье мы поговорим об архитектурных шаблонах, используемых в Android-приложениях.

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

Возможно, я плохо искал, но в документации Android нет упоминания о каких-либо шаблонах. Не смотря на это, в Android реализованы некоторые шаблоны и архитектурные стили, о которых мы сейчас и поговорим.

Архитектура Android является фреймворк-ориентированной (framework-based), в противовес вольной (free-style) архитектуре.

В чём разница? Вольные приложения, написанные на Java, начинаются с класса, имеющего метод main(), и разрабатываются в полном соответствии с настроением разработчика.

В противоположность этому фреймворк-ориентированные приложения основываются на существующем фреймворке. Их разработка сводится к расширению неких классов или реализации интерфейсов, предоставленных фрейморком. Такое приложение не может быть запущено вне фреймворка или без него. Примером могут быть веб-приложения на Java, в которых разработчики реализуют интерфейс Servlet или расширяют одну из его реализаций, или приложения Eclipse RCP, в котором разработчик расширяет один из классов Editor или View.

Фреймворк-ориентированная архитектура ограничивает свободу разработчиков, предписывая им что и как следует делать. Но, в итоге, исчезают повторяющиеся участки кода (boilerplate code), и разработчикам приходится (хотелось бы в это верить) тщательно следовать шаблонам проектирования.

Для Java существует множество фреймворков. Тем не менее, команда Android решила создать свой собственный. Возможно, одной из причин, по которой они так поступили, была необходимость поддерживать уникальную систему управления памятью.

В «обычной» Java объекты находятся в памяти до тех пор, пока сборщик мусора не доберётся до них. Происходит это только тогда, когда на объект нет ни одной ссылки от «живых» объектов (подробнее можно почитать здесь). В Android это не так. Если некий интерфейс пользователя скрывается (то есть он более не видим на экране), то нет никакой гарантии, что он находится в памяти, даже есть приложение в дальнейшем собирается использовать его. Если у ОС Android есть достаточно свободной памяти, эти объекты могут храниться в ней, но сборщик мусора может уничтожить их в любой момент, когда ОС решит, что памяти осталось слишком мало. То же верно и для процессов. Процесс, который в данный момент времени не показывает пользователю никакого графического интерфейса, может быть уничтожен ОС Android на абсолютно законных основаниях (есть одно исключение из этого правила — сервисы; об этом мы поговорим позже).

Рассмотрим пример. Пусть наше приложение имеет экраны A и B. Пользователь сначала открывает экран A, а затем экран B; с этого момента экран A стал невидим. Это означает, что экран A и вся логика, содержащаяся в нём, может находиться в памяти, а может и не находиться. Так, нет гарантий, что объекты, связанные с экраном A находятся в памяти, пока виден экран B. Логика экрана B не должна завязываться на нахождение объектов экрана A в памяти. Побочный эффект состоит в том, что архитектура Android принуждает к использованию архитектурного стиля стиля «shared nothing». Это означает, что разные части Android приложения могут вызывать друг друга и взаимодействовать между собой только формально; ни один из них не может обратиться к другому напрямую.

Хорошо, а что случится, если пользователь решит вернуться на экран A? Наверное, он захочет увидеть его в том же состоянии, в котором он оставил его, верно? Вот как фреймворк Android решает эту проблему: для каждого состояния жизненного цикла существуют методы, каждый из которых может быть переопределён разработчиком. Эти методы вызываются фреймворком в заранее определённые ключевые моменты, например, когда пользовательский интерфейс показывается на экране, прячется и т.п. В этих методах разработчик может реализовать логику для хранения и восстановления состояния объектов.

Читайте также:  Меч обои для андроид

Подобная обработка скрытия пользовательских интерфейсов и существование кнопки «назад» на Android-устройствах приводит к необходимости наличия стека пользовательских интерфейсов, в котором текущий видимый интерфейс помещается на вершину, а все остальные сдвигаются вниз (стековая операция «push»). Нажатие «назад» удаляет интерфейс с вершины стека и показывает элемент, который был за ним (стековая операция «pop»). Подобный стек существует в Android. В документации он называется «activity stack» или иногда «back stack».

В плане обработки взаимодействия между пользовательским интерфейсом и его логикой Android следует архитектурному шаблону «Model-View-ViewModel» (MVVM). Для разработчиков это хорошая новость, поскольку MVVM — самая лучшая архитектура GUI-приложений на настоящий момент.

Архитектура MVVM была создана с целью разделения труда дизайнера и программиста, которое невозможно, когда Java-разработчик пытается построить GUI в Swing или разработчик на Visual C++ пытается создать пользовательский интерфейс в MFC. Разработчики — сообразительные парни и имеют множество навыков, но создание удобных и привлекательных интерфейсов требует абсолютно других талантов, нежели те, которыми они обладают разработчики. Эта работа больше подходит для дизайнеров интерфейсов. Хорошие дизайнеры интерфейсов лучше знают, чего хотя пользователи, нежели эксперты в области проектирования и написания кода. Понятно, будет лучше, если дизайнер интерфейсов создаст интерфейс, а разработчик напишет код, который реализует логику этого интерфейса, но технологии типа Swing или MFC просто-напросто не позволяют поступать таким образом.

Архитектура MVVM решает эту проблему ясным разделением ответственности:

  • Разработка пользовательского интерфейса совершается дизайнером интерфейсов с помощью технологии, более или менее естественной для такой работы (XML)
  • Логика пользовательского интерфейса реализуется разработчиком как компонент ViewModel
  • Функциональные связи между пользовательским интерфейсом и ViewModel реализуются через биндинги (bindings), которые, по сути, являются правилами типа «если кнопка A была нажата, должен быть вызван метод onButtonAClick() из ViewModel». Биндинги могут быть написаны в коде или определены декларативным путём (Android использует оба типа).

Архитектура MVVM используется в том или ином виде всеми современными технологиями, например Microsoft WPF и Silverlight, Oracle JavaFX, Adobe Flex, AJAX.

Мы упоминали, что различные части Android-приложения могут вызывать друг друга и взаимодействовать между собой только формально. Как же это достигается? Фреймворк Android использует несколько шаблонов взаимодействия:

  • Обмен сообщениями с помощью класса Intent
  • Наблюдатель с использованием классов Intent и BroadcastReceiver
  • Позднее связывание с последующим вызовом метода используется для доступа к контент-провайдерам (ContentProviders) и локальным (внурипроцессным) сервисам (Services)
  • Позднее связывание и межпроцессное взаимодейтсвие (Inter-process Procedure Communication, IPC) для вызова сервисов (AIDL)

Не волнуйтесь, если что-то из этого звучит непонятно. Подробные объяснения будут в следующих статьях.

Источник

Шаблоны проектирования при разработке под Android. Часть 1 — Введение

Писать программки для смартфонов — мое хобби. Все началось с того, что я купил свой первый смартфон Nokia E51 на Symbian и мне очень нравилось что его функционал можно было расширить через установку дополнительных программ.
Но однажды я не нашел необходимой программы и решил написать ее сам. Так и началось мое увлечение программами для смартфонов.

После того как глава Nokia заявил, что дни Symbian сочтены, я решил изучить платформу Android.

Для лучшего усвоения материала я решил написать полезную, хотя бы для себя, программку. Но написать ее не по детски, когда куски примитивного кода копируются из документации, а по взрослому с разработкой архитектуры, и использованием современных технологий программирования TDD, MVP и IoС.

Постановка задачи

Мое первое приложение для Android — T-Alarm. Найти его можно на Android Market по названию. На данный момент в программе нет дизайна и она выглядит немного некузяво, но вскоре дизайн появится.

Это просто программа будильник, но с одной функцией, которой нет в других программах.

Обычно я встаю в 6:45 утра, но пару раз в неделю мне надо встать в другое время, например для утренней пробежки. Для этого надо изменить время в будильнике на завтра, а так же не забыть вернуть потом расписание в исходное. Все остальные будильники на Android не позволяют быстро поменять время на завтра, для этого надо долго ходить по настройкам, а так же никто из них сам не возвращает время в исходное состояние после срабатывания по измененному.
Поэтому я решил, что основной фишкой моей программы будет возможность однократного изменения времени следующего срабатывания, а также общий принцип, что для внесения изменений в расписание надо как можно меньше времени тратить на блуждание по настройкам.

Читайте также:  Почему виндовс не видит андроид через юсб

Более того, будильник является отличной задачей, чтобы по глубже изучить платформу Andorid. Здесь затрагиваются такие части как:
— Пользовательский интерфейс. Надо сделать несколько окон для задания настроек.
— воспроизведение музыкальных файлов. Можно изучить возможности встроенного медиа-проигрывателя
— Сохранение расписания в БД. Теперь я знаю как пользоваться базой данных SQLIte на Android
— Реализация сервисов для отработки будильника. При наступлении часа Х надо запрограммировать следующий момент срабатывания, с учетом нескольких дреманий (snooze), и сыграть побудку. Прекрасный повод разобраться в том какие сервисы есть в Android и какой надо использовать.
— Получение различных сигналов от ОС. Сервис будильника должен срабатывать по системному будильнику и при загрузке смартфона.

Этой статей я открываю ряд статей, где хочу поделиться своим опытом разработки. Причем я хочу сосредоточиться на использовании MVP и TDD при разработке моего приложения. В интернете я нашел все это по кускам и смог собрать во едино. Это позволило мне сделать приложение в котором все основные алгоритмы протестированы с помощью UnitTest-ов, а так же я обраружл несколько других вкусностей, которые будут интересны Andorid разработчикам.

Общая архитектуры проектов и приложения

С самого начала я хотел разобраться как можно использовать современные подходы и шаблоны проектирования при разработке приложений для Android и поэтому много времени у меня ушло на изучения различных Framework-ов. Вроде бы в Android SDK уже встроен JUnit для организации тестов и есть много статей в интернете как им пользоваться, но как дело доходит реального проекта сразу появляются подводные камни. О том как их преодолеть я и расскажу в этом цикле статей.

Итак, я решил использовать TDD для того, чтобы быть уверенным, что все основные алгоритмы моего приложения протестированы. Так я остановился на шаблоне MVP при проектировании пользовательского интерфейса.

Организация проектов

Мои исходники разделены на два проекта — основной проект с исходниками и тестовй проект с тестами.

Проект с исходниками состоит из нескольких пакетов. Как правило один пакет это одно архитектурное звено, то есть одна форма или сервис.

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

Проект с тестами тоже разбит на пакеты. Каждый пакет содержит несколько тестов для соответствующего звена приложения.

Архитектура приложения

Поскольку мое приложение маленькое, то в нем нет слоев, а есть только несколько звеньев:

1. Главное окно
2. Окно редактирования будильника
3. Окно выбора мелодии
4. Окно при звонке
5. Модель данных, в моем случае это список будильников, и репозиторий для сохранения модели в БД.
6. Сервис для обработки системных сообщений: наступление часа Х и загрузка смартфона.

Все окна и сервис работают только с моделью, которую получают из репозитория. Благодаря этому получается архитектура состоящая из слабосвязанных звеньев. Каждое звено можно тестировать отдельно от других имитируя модель.

Так же сама модель содержит сложную логику расчета следующего будильника, но модель так же легко тестируется, поскольку она не зависит от других звеньев.

Читайте также:  Plants vs zombies без рекламы для андроид

В данной архитектуре непротестированными остаются только представления. Но код в них как правило предельно прост. Это просто маппинг параметров метода в контролы формы. Как правило этот код тестируется методом «пристального взгляда». А ошибки легко обнаруживаются когда вы видите что на форме не заполнен какой-то контрол.

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

Источник

Android developer design pattern

Since the very beginning, one of the most annoying aspects of using VectorDrawable s on Android has been the lack of a reliable SVG converter. Google has recently made huge strides towards improving Android Studio’s SVG-to- VectorDrawable tool in order to improve this experience.

However, there has always been one major issue for me: the tool doesn’t support batch conversion of SVGs and can’t be invoked from the command line. Working at Lyft, it’s not uncommon for me to need to convert hundreds of SVGs into VectorDrawable s at a time. Having to go through Android Studio’s GUI in order to convert each SVG one-by-one is simply not realistic.

Introducing Kyrie — An Alternative to Animated Vector Drawables

Today I am open sourcing the first alpha release of an animation library I’ve been writing named Kyrie. Think of it as a superset of Android’s VectorDrawable and AnimatedVectorDrawable classes: it can do everything they can do and more.

Experimenting with Nested Scrolling

One of the coolest projects I worked on during my 3 years at Google was Google Expeditions, a virtual reality app that allows teachers to lead students on immersive virtual field trips around the world. I especially enjoyed working on the app’s field trip selector screen, which renders a SurfaceView behind a beautifully designed card-based layout that allows the user to quickly switch between different VR experiences.

An Introduction to Icon Animation Techniques

Creative customization is one of the tenets of material design; the subtle addition of an icon animation can add an element of wonder to the user experience, making your app feel more natural and alive. Unfortunately, building an icon animation from scratch using VectorDrawable s can be challenging. Not only does it take a fair amount of work to implement, but it also requires a vision of how the final result should look and feel. If you aren’t familiar with the different techniques that are most often used to create icon animations, you’re going to have a hard time designing your own.

This blog post covers several different techniques that you can use to create beautiful icon animations. The best way to learn is by example, so as you read through the post you’ll encounter interactive demos highlighting how each technique works. I hope this blog post can at the very least open your eyes to how icon animations behave under-the-hood, because I genuinely believe that understanding how they work is the first step towards creating your own.

Coloring Buttons w/ ThemeOverlays & Background Tints

Say you want to change the background color of a Button . How can this be done?

This blog post covers two different approaches. In the first approach, we’ll use AppCompat’s Widget.AppCompat.Button.Colored style and a custom ThemeOverlay to modify the button’s background color directly, and in the second, we’ll use AppCompat’s built-in background tinting support to achieve an identical effect.

+1 this blog!

Android Design Patterns is a website for developers who wish to better understand the Android application framework. The tutorials here emphasize proper code design and project maintainability.

Find a typo?

Submit a pull request! The code powering this site is open-source and available on GitHub. Corrections are appreciated and encouraged! Click here for instructions.

Источник

Оцените статью