В данной статье мы опираемся на собственное мнение и профессиональный опыт, учитывая разнообразные точки зрения в сообществе разработчиков Android, а также постоянно изучая руководства, предоставляемые Google для Android.
Важно отметить, что существуют увлекательные инструменты, шаблоны и архитектуры, о которых мы не упоминаем, но это не означает, что они не могут быть интересными альтернативами при разработке приложений для Android.
Что такое Android?
Android, разработанный Google, является операционной системой с открытым исходным кодом, основанной на ядре Linux. Он применяется в широком спектре устройств, включая смартфоны, планшеты, телевизоры и смарт-часы.
На данный момент Android является самой распространенной операционной системой для мобильных устройств в мире. Согласно отчету Statcounter, за последние 12 месяцев доля Android на рынке составляет 71,96%.
Далее мы представляем перечень инструментов, библиотек, архитектур, руководств и других полезных утилит, которые, по нашему мнению, играют важную роль в разработке современных приложений для Android.
Kotlin
Kotlin является языком программирования, созданным компанией JetBrains. Он был официально рекомендован Google в мае 2017 года. Kotlin представляет собой современный язык программирования, совместимый с Java и способный работать на JVM, что способствует быстрому принятию его для разработки приложений Android.
Безусловно, независимо от вашего уровня опыта в Android, следует рассмотреть Kotlin в качестве основного языка программирования и не идти против течения. Фактически, Google официально объявил об этом подходе на конференции I/O 2019. Используя Kotlin, вы сможете воспользоваться всеми преимуществами современного языка, включая мощные возможности корутин и библиотек, специально разработанных для экосистемы Android.
Jetpack Compose
Jetpack Compose представляет собой современный рекомендуемый набор инструментов для создания нативного пользовательского интерфейса, который упрощает и ускоряет разработку UI для Android.
Jetpack Compose является частью библиотеки Android Jetpack и использует язык программирования Kotlin для удобного создания нативного пользовательского интерфейса. Он также интегрируется с другими библиотеками Android Jetpack, такими как LiveData и ViewModel, для упрощения разработки реактивных и поддерживаемых Android-приложений.
Далее перечислены некоторые ключевые особенности Jetpack Compose:
- Декларативный подход к созданию интерфейса.
- Возможность настройки виджетов.
- Простая интеграция с существующим кодом.
- Возможность предварительного просмотра изменений в реальном времени.
- Улучшенная производительность
Android Jetpack
Jetpack представляет собой набор библиотек, которые помогают разработчикам применять передовые методы, уменьшать объем шаблонного кода и писать код, который работает одинаково на всех версиях и устройствах Android. Это позволяет разработчикам сосредоточиться на том, что они на самом деле интересуются.
Ниже перечислены некоторые из наиболее распространенных инструментов Jetpack:
- ViewModel
- Room
- DataStore
- WorkManager
- Navigation
- CameraX
- Compose
Material Design
Material Design представляет собой гибкую систему руководств, компонентов и инструментов, которая поддерживает передовые практики в области дизайна пользовательского интерфейса. Открытый исходный код Material Design способствует совместной работе между дизайнерами и разработчиками, помогая командам быстро создавать привлекательные продукты.
Material Design разрабатывается дизайнерами и разработчиками из Google и предоставляет единое руководство по созданию пользовательских интерфейсов для Android, Flutter и веб-платформы.
Чистая архитектура
Роберт С. Мартин представил концепцию "чистой архитектуры", которая основывается на принципе разделения ответственности путем разделения кода на слои.
Основные характеристики чистой архитектуры включают:
- Независимость от конкретных фреймворков.
- Возможность проведения тестирования.
- Независимость от пользовательского интерфейса.
- Независимость от базы данных.
- Независимость от внешних агентов.
- Соблюдение правила зависимостей.
Правило зависимостей
Автор детально описывает правило зависимостей в статье "The Clean Code Blog", предоставляя подробное объяснение данного принципа.
Основное правило, благодаря которому эта архитектура работает, называется правилом зависимостей. Это правило гласит, что зависимости исходного кода могут указывать только внутрь. Ничто во внутреннем круге не может вообще ничего знать о чем-то во внешнем круге. В частности, имя чего-либо, объявленного во внешнем круге, не должно упоминаться в коде во внутреннем круге. Это включает в себя функции, классы, переменные или любой другой именованный программный объект.
Чистая архитектура в Android:
- Компоненты представления: Activities, Fragments, View Model и другие элементы, которые отвечают за отображение данных пользователю.
- Компоненты домена: Use Cases, Entities, Repositories и другие элементы, которые определяют бизнес-логику и правила работы приложения.
- Компоненты данных: реализации Repository, мапперы, DTO и другие элементы, которые обеспечивают доступ к данным и их обработку.
Архитектурные паттерны для уровня представления
Архитектурные паттерны представляет собой стратегию верхнего уровня, которая помогает в разработке архитектуры ПО. Его особенность заключается в том, что он служит решением типовых архитектурных вопросов, формируя повторно используемую схему или структуру. Эти шаблоны имеют сходство с шаблонами проектирования, но они более обширны и затрагивают более крупномасштабные вопросы, включая общую организацию системы, взаимодействие между компонентами и методы управления данными.
На уровне представления существует несколько архитектурных шаблонов, которые я хотел бы выделить:
- MVVM (Model-View-ViewModel)
- MVI (Model-View-Intent)
Не будем углубляться в подробности каждого из них, так как в Интернете вы можете найти обширную информацию на эту тему.
Dependency injection
Внедрение зависимостей (Dependency Injection) - это паттерн проектирования программного обеспечения, который позволяет клиентскому коду получать свои зависимости из внешнего источника, а не создавать их самостоятельно. Этот подход обеспечивает инверсию управления (Inversion of Control, IoC) между объектами и их зависимостями.
Некоторые популярные инструменты для реализации внедрения зависимостей в Android:
- Hilt - это библиотека, разработанная Google, которая обеспечивает автоматическое внедрение зависимостей в приложениях Android, упрощая процесс создания и предоставления зависимостей.
- Dagger - это мощный инструмент для внедрения зависимостей, разработанный компанией Google. Он предоставляет гибкую конфигурацию и генерирует эффективный и быстрый код для удовлетворения зависимостей.
- Koin - это легковесный инструмент для внедрения зависимостей на языке Kotlin. Он прост в использовании и обеспечивает гибкость при организации ваших зависимостей.
- Kodein - ещё один фреймворк для внедрения зависимостей на Kotlin, который предоставляет простой и декларативный подход к описанию зависимостей.
Использование таких инструментов значительно упрощает управление зависимостями в проекте и помогает сделать код более модульным и тестируемым.
Модульность
Модуляризация - это подход в проектировании программного обеспечения, который способствует разделению приложения на отдельные независимые модули, каждый из которых обладает своей собственной функциональностью и ответственностью.
Преимущества модульности:
- Возможность повторного использования: Разделение приложения на независимые модули позволяет повторно использовать их в различных частях приложения или даже в других приложениях.
- Строгий контроль видимости: Модули обеспечивают удобный контроль над тем, что предоставляется другим частям кодовой базы.
- Настраиваемая доставка: Play Feature Delivery использует расширенные возможности пакетов приложений, позволяя предоставлять определенные функции приложения по требованию или в зависимости от условий.
- Масштабируемость: Независимые модули позволяют добавлять или удалять функциональность без влияния на другие части приложения.
- Простота обслуживания: Разделение приложения на независимые модули с определенной функциональностью и ответственностью упрощает понимание и поддержку кода.
- Простота тестирования: Имея независимые модули, их можно тестировать изолированно, что упрощает обнаружение и исправление ошибок.
- Улучшение архитектуры: Модульность способствует улучшению архитектуры приложения, обеспечивая более организованную и структурированную кодовую базу.
- Улучшение совместной работы: Разработчики могут работать над различными частями приложения одновременно и без помех благодаря наличию независимых модулей.
- Время сборки: Функции Gradle, такие как инкрементная сборка, кеширование сборки или параллельная сборка, могут использовать модульность для повышения производительности сборки.
Сеть
- Ktor
- OkHttp
- Retrofit
Сериализация
В этом разделе мы хотели бы подчеркнуть значимость двух инструментов: Moshi, широко используемого совместно с Retrofit, и Kotlin Serialization, представляющего команду Kotlin в Jetbrains.
- Moshi
- Kotlin Serialization
Moshi и Kotlin Serialization представляют собой пару библиотек для сериализации/десериализации в Kotlin и Java. Они облегчают процесс преобразования объектов в JSON или другой формат сериализации, и обратно. Их интерфейсы удобны и оптимизированы для применения в мобильных и настольных приложениях. Можно сказать, что основной акцент Moshi сосредоточен на JSON-сериализации, в то время как Kotlin Serialization поддерживает множество форматов сериализации, включая JSON.
Загрузка изображения
Существуют несколько сторонних библиотек, доступных для загрузки изображений из Интернета, которые могут помочь вам справиться с этим процессом. Библиотеки, предназначенные для загрузки изображений, берут на себя большую часть сложной работы. Они автоматически обрабатывают кэширование (чтобы изображение не загружалось несколько раз) и осуществляют сетевую логику для загрузки и отображения изображения на экране.
- Coil
- Glide
Реактивность/управление потоками
Когда речь идет о реактивном программировании и асинхронных процессах, наш первый выбор обычно падает на Kotlin Coroutines. С помощью функций приостановки (Suspension Functions) и Flow, мы можем удовлетворить все эти требования. Однако я считаю, что важно отметить значимость RxJava в разработке приложений для Android в этом контексте. Для тех, кто работает с Android всего несколько лет, можно сказать, что RxJava является мощным инструментом с обширным набором функций для работы с потоками данных. Мы все еще считаем, что RxJava представляет интересную альтернативу для реактивности в настоящее время.
- Kotlin Coroutines
- RxJava
Локальное хранение данных
Когда мы создаем мобильные приложения, важным аспектом является возможность сохранения данных локально, например, данных сеанса или кэша. При выборе способа хранения необходимо учесть потребности вашего приложения. Мы можем сохранять неструктурированные данные, такие как пары ключ-значение, или структурированные данные, представленные в виде таблиц в базе данных. Важно отметить, что здесь мы упоминаем не все типы локального хранилища, которые доступны (например, файловое хранилище), а только инструменты, позволяющие сохранять данные.
Предложения:
- DataStore
- EncryptedSharedPreferences
Тестирование
- JUnit 5
- Mockk
- Espresso
- Robolectric
Оптимизация R8
R8 - это компилятор по умолчанию, который преобразует Java-байт-код вашего проекта в формат DEX, подходящий для платформы Android. Этот инструмент помогает обфусцировать и уменьшить размер кода приложения путем сокращения имен классов и их свойств, а также удаления неиспользуемого кода и ресурсов внутри проекта. Если вы хотите узнать больше, рекомендуется ознакомиться с документацией Android о методах сжатия, обфускации и оптимизации вашего приложения.
Play Feature Delivery
Google Play использует модель обслуживания приложений, известную как динамическая доставка, которая основана на Android App Bundle. Эта модель позволяет создавать и обслуживать оптимизированные APK-файлы для каждой конфигурации устройства пользователя. В результате пользователи загружают только необходимый им код и ресурсы для запуска вашего приложения.
Адаптивная верстка
С увеличением числа мобильных устройств с разными форм-факторами становится необходимым иметь инструменты, позволяющие создавать Android-приложения, адаптированные под различные типы экранов. В этой связи Android предоставляет нам классы размеров окон, которые определяют три основные группы экранов для разработки проектов. Это позволяет нам избежать сложностей и принятия решений относительно множества дизайн-вариантов, сокращая их до трех групп: Compat (совместимый), Medium (средний) и Expanded (расширенный).
Таким образом, классы размеров окон предоставляют нам удобный подход для адаптации наших Android-приложений к различным экранам.
Производительность
Мы должны стремиться обеспечить отличный пользовательский опыт не только при запуске приложения, но и на протяжении всего его существования. Поэтому важно иметь доступ к инструментам, которые позволяют проводить предварительный анализ и непрерывно мониторить случаи, которые могут повлиять на производительность приложения. Вот некоторые инструменты, которые могут помочь вам в этом:
- Benchmark
- Baseline Profiles
- App Startup
- Firebase Performance Monitoring
- JankStats library
Обновления в приложении
При обновлении вашего приложения пользователи получают доступ к новым функциям, улучшенной производительности и исправлениям ошибок. Некоторые пользователи автоматически включают фоновые обновления, когда их устройство подключено к неограниченному интернет-соединению, но другим может потребоваться напоминание о необходимости установки обновлений. Функция обновлений в приложении является частью библиотеки Google Play Core и предлагает активным пользователям обновить ваше приложение.
Функция обновлений в приложении поддерживается на устройствах с операционной системой Android 5.0 (уровень API 21) и выше. Она доступна только для мобильных устройств Android, планшетов Android и устройств Chrome OS.
Отзывы в приложении
С помощью Google Play In-App Review API пользователи могут оценивать и оставлять отзывы в Play Store прямо из вашего приложения или игры, без необходимости покидать его.
Обычно процесс запроса отзыва в приложении может быть запущен в любое время во время использования приложения пользователем. При запросе пользователь может проставить оценку от 1 до 5 звезд и добавить необязательный комментарий. После отправки, отзыв будет передан в Play Store и в конечном итоге отображен там.
Важно соблюдать строгие правила, которые гарантируют конфиденциальность пользователей и предотвращают неправомерное использование API. Эти правила касаются времени запроса отзыва в приложении и дизайна самого запроса, и ваше приложение должно следовать им.
Доступность
Одной из важных функций при проектировании и разработке программного обеспечения является обеспечение доступности, что позволяет людям с ограниченными возможностями использовать приложение и улучшает их взаимодействие с интерфейсом. Эта концепция направлена на улучшение различных видов инвалидности, таких как проблемы со зрением, дальтонизм, проблемы со слухом, ограниченная моторика пальцев, когнитивные нарушения и другие.
В рамках этой концепции можно применять следующие подходы:
- Улучшение видимости текста: варианты включают изменение цветовой контрастности текста и возможность изменения его размера в соответствии с предпочтениями пользователя.
- Использование больших и простых элементов управления: приложение может быть спроектировано с использованием крупных и понятных кнопок, полей ввода и других элементов управления, чтобы упростить их обнаружение и нажатие для людей с ограниченной моторикой или проблемами зрения.
- Предоставление описания каждого элемента пользовательского интерфейса: каждый элемент, такой как кнопка, ссылка или изображение, может быть сопровожден текстовым описанием или альтернативным текстом, чтобы люди с проблемами зрения или когнитивными нарушениями могли понять его назначение и функцию.
Эти подходы помогают сделать программное обеспечение более доступным и инклюзивным, позволяя людям с различными ограничениями использовать приложение и эффективно взаимодействовать с ним.
Безопасность
При разработке приложений безопасность является одним из наиболее важных аспектов, если не самым важным. Необходимо обеспечить защиту целостности устройства, безопасность данных и доверие пользователей. В связи с этим, ниже приведены некоторые рекомендации, которые помогут вам в этом.
- Обеспечение шифрования конфиденциальных данных и файлов: рекомендуется использовать EncryptedSharedPreferences и EncryptedFile для хранения и обработки конфиденциальной информации.
- Применение разрешений на основе цифровой подписи: использование подписанных разрешений позволяет установить доверие между приложением и системой, а также защитить приложение от несанкционированного доступа.
- Использование разрешений на основе подписи при обмене данными между управляемыми вами приложениями: это помогает обеспечить безопасность при передаче информации между различными компонентами приложений.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp">
<permission android:name="my_custom_permission_name" android:protectionLevel="signature" /> - Избегайте сохранения ключей, токенов или конфиденциальных данных, необходимых для настройки вашего приложения, непосредственно в файлах или классах, которые хранятся в репозитории проекта. Вместо этого рекомендуется использовать файл local.properties, чтобы хранить такую информацию безопасным образом.
Обращение к local.properties:
val properties = Properties()
properties.load(FileInputStream("local.properties"))
val apiKey = properties.getProperty("api_key")
Каталоги версий
Gradle предоставляет стандартный механизм централизованного управления зависимостями проекта, известный как "каталог версий". Этот механизм был представлен как экспериментальная функция в версии 7.0 и официально включен в версию 7.4.
Преимущества этого подхода включают:
- Автоматическая генерация типобезопасных методов доступа для каждого каталога Gradle. Это позволяет легко добавлять зависимости с помощью автозаполнения в среде разработки (IDE).
- Каждый каталог доступен для всех проектов в рамках сборки. Это централизованное место для объявления версий зависимостей и обеспечения применения этих изменений ко всем подпроектам.
- Каталоги могут объявлять пакеты зависимостей, которые представляют собой "группы зависимостей", которые часто используются вместе.
- Каталоги позволяют отделить группу и имя зависимости от ее фактической версии и использовать ссылки на версию. Это позволяет совместно использовать объявление версии между несколькими зависимостями.
Логирование
Логирование является программным инструментом, который служит для регистрации информации о выполнении программы. Он используется для зафиксирования важных событий, сообщений об ошибках, отладочных сообщений и прочей информации, которая может быть полезна при диагностике проблем или понимании работы программы. Логи можно настроить таким образом, чтобы сообщения записывались в различные места, такие как журнальный файл, консоль, база данных или отправлялись на сервер регистрации.
- Timber
Линтер
Линтер - это инструмент, который применяется для анализа исходного кода программы с целью обнаружения потенциальных проблем или ошибок в коде. Эти проблемы могут быть связаны с синтаксисом, неправильным стилем кодирования, отсутствием документации, проблемами безопасности и другими аспектами, которые могут повлиять на качество и обслуживаемость кода. Линтер помогает выявить такие проблемы и предлагает рекомендации для их исправления, улучшая тем самым качество кода и его удобство сопровождения.
Линтеры для Android:
- Android Lint
- Detekt
- Ktlint