С одной стороны, статья для тех, кто уже прошел все основы, может собрать полноценное нативное приложение под андроид любой сложности и не знает, чем занять себя в свободное время.
С другой - перечисленные технологии становятся новой реальностью. И теперь просто знать о мультипоточности, ViewModels и LiveData становится недостаточно.
Цель статьи
Собираем список технологий\библиотек\фреймворков, которые нужно понять за этот год, если собираетесь проходить собеседования в компании, следящими за модой.
все нижеописанные технологии — лишь надстройки над базовыми компонентами
не обязательно знать их, чтобы написать отличное приложение
но если хотите придерживаться современных течений - айда читать документацию
Список
Далее будет идти список и краткое описание, объясняющее концепцию технологии и боль, которую она решает. Максимально коротко.
Compose
Compose — новый метод верстки.
Решает проблемы:
пропадает разделение кодовой базы — отпадает нужда в xml-файлах, оставляем только Kotlin
не нужно больше искать вьюшки по id и следить, чтобы значения обновлялись - грубо говоря, поля вьюшки подписываются на значения из viewModel и сами обновляются
не нужно больше следить за жизненным циклом (при правильной архитектуре библиотеки сами учитывают состояние lifecycler)
избавляет от наследования во вьюшках - переходим к композиции простых элементов
Flow
Flow (StateFlow, SharedFlow...) — асинхронный способ передачи данных по подписочной модели. По принципу Flow — это LiveData с кучей настроек, с завязкой на корутины и без завязки на lifecycler-компонент.
Решает проблемы:
-
передача данных от Database (Source) к View теперь может выглядеть как тунель без ответвлений - Database испускает данные в flow, их забирает ViewModel и пересылает во View
Да, та самая "чистая архитектура", которой сто лет, но теперь есть средство нагляднее показать идеальный "поток" данных
можно гибко настроить буффер - указать количество хранимых элементов, выбрать сценарий переполнения и определить, что делать, если пришли новые данные, а старые еще не обработаны подписчиком
Kotlin sealed class/interface
Это не целая технология, но эта фишка языка часто используется вместе с Flow и Compose, потому что идеально подходит для описания состояний.
Решает проблемы:
-
можно описывать состояния (States)
например, описать все состояния экрана - DataLoadedState, DataLoadingState, EmptyResultState....
результаты выполнения функции - Success<T>, Error(e: Throwable), Loading...
Подробнее о возможностях, отличиях от Enum и способах применения писал пост в tg-канале об android-разработке: https://t.me/dolgo_polo_dev/52
Kotlin delegation
Еще один сахар из котлина — синтаксическое средство, позволяющее делегировать методы getValue() и setValue() какому-то классу.
Например, оператор by lazy() делегирует метод getValue(), что позволяет инициализировать значение переменной только при первом обращении (а не в момент объявления.
Решает проблемы:
есть готовые делегаты - by lazy(), by viewModels()...
можно написать свои делегаты, избавившись от шаблонного кода
можно хранить свойства в ассоциативном списке
Hilt
Hilt — фреймворк для внедрения зависимостей, замена Dagger 2
Решает проблемы:
как и все dependency injection библиотеки - прям код создания объектов, управляет жизненный циклом и количеством создаваемых объектов
преимущество перед Dagger 2 - предоставляет собственные скопы (Scope) для всех стандартных элементов - Activity, Fragment, ViewModel, Service... - не нужно писать свои
преимущество перед Dagger 2 - не нужно писать ViewModelFactory для инъектирования во ViewModel
преимущество перед Dagger 2 - достаточно написать Module-классы, в которых объявлены Provide и Bind-функции, и ставить аннотацию @Inject
Coroutine
Корутины — пишем асинхронный код без явных коллбеков и явной работы с потоками
Решают проблемы:
код становится пошаговым, не нужно отслеживать макароны из коллбеков
если использовать правильно, приложение работает без тормозов, так как главный поток занят только отрисовкой UI
с помощью CoroutineScope и родительских отношений между корутинами можно легко прерывать выполнения функции в любом момент, если в ней больше нет нужды (например, viewModelScope автоматически остановится, когда ViewModel будет уничтожена из-за того, что пользователь ушел с экрана)
MVI
MVI — архитектура. Про ее минусы и плюсы можно бесконечно, но суть одна - многие вышеописанные технологии заточены под ее философию:
заранее описываем все возможные состояния и эффекты, и от класса к классу передаем не информацию, а информацию, обернутую в состояние
Navigation Components
NavComponents — способ описания взаимодействия экранов или же способ создания наглядной карты приложения
Решает проблемы:
не надо держать в голове или в макете, с какого экрана на какой можно перейти - в Android Studio строится визуальный граф
можно описать заранее, какие данные должны передавать экраны друг другу
нельзя случайно увести пользователя по пути, не описанному в графе
WorkManager
WorkManager — упрощает работу с запуском и контролем жизненного цикла сервисов (Service)
Решает проблемы:
очевидно - легче отслеживать, какие службы запущены, и задавать условия их смерти
становится удобнее создавать отложенные службы (в том числе те, что должны отработать после перезагрузки устройства)
в Android Studio добавили отладочное средство, которое позволяет отслеживать состояние сервисов, управляемых WorkManager
Где еще получать обзорную информацию
Если вам, как и мне, нравится подобный формат — краткий обзор концепции технологий с минимальным погружением в код, то предлагаю:
поддержать статью
оценить tg-канал об Android-разработке — с картинками и короткими постами для новичков и бывалых — Dolgo.Polo Dev Android @dolgo_polo_dev
Комментарии (28)
grishkaa
22.02.2022 07:45+4Не надо становиться модным, надо становиться нормальным :)
Даже если отбросить мою личную неприязнь к котлину, проблема использования модных гугловских абстракций поверх SDK в том, что они постоянно меняются и никогда не готовы. Одно уже задепрекейтили, а предлагаемая замена всё ещё в бете. Та же навигация — гугл уже, наверное, третье или четвёртое по счёту решение на эту тему представляет, я уже перестал за всем этим следить, просто написал свой простенький стек для системных фрагментов и пользуюсь им. Да, даже appcompat на самом деле не нужен.dimskiy
22.02.2022 10:08Вы, мягко говоря, преувеличиваете. Та же nav library все та же как была, только обновляется регулярно. Не помню когда там были последний раз breaking changes :)
Да, даже appcompat на самом деле не нужен.
????♂️
Вы простите, но когда человек не занимается каким-то направлением разработки, то ему и не судить бы о его (направлении) специфике, верно?
grishkaa
22.02.2022 10:11+1Вы простите, но когда человек не занимается каким-то направлением разработки, то ему и не судить бы и о ее специфике, верно?
Вы простите, но я занимаюсь разработкой под андроид 10 лет, 5 из которых писал официальное приложение ВКонтакте, большую часть времени как единственный разработчик. Наверное, я хотя бы чуть-чуть в этом разбираюсь.dimskiy
22.02.2022 12:50Просто ваш комментарий, на мой взгляд, не мэтчится с этим фактом. Но ок, наверное вы чтото другое хотели сказать
ps. Ни на что не намекаю, но можно и за 5 лет не продвинуться особо, я встречал такие примеры. Просто не будем гнуть пальцы ;)
Neikist
22.02.2022 13:15Вы и правда ни на что не намекаете. Григорий то человек известный в коммьюнити, хоть и взглядов придерживается не стандартных. Офф клиенты вк и телеги писал тех же.
З.Ы. Сам придерживаюсь чего то среднего. С одной стороны современное коммьюнити чрезмерно упоролось абстракциями и «архитектурами», с другой писать на голой java и всюду вставлять проверки на версию SDK по мне тоже как то перебор.Dreddik
23.02.2022 00:34Всем сердцем люблю Гришу, но зачастую сложно мириться с его хейтом "просто потому что".
quaer
22.02.2022 16:49Вдумайтесь - каждое приложение тащит за собой androidx. Хорошо хоть не целую ява-машину. Как пример, приложение без него - 200 кБ, с ним - 2 мб с лишним.
И при этом полная мешанина в стилях, где теперь надо их менять для сходных стилей в разных неймспейсах, а стоит немного ошибться, например вместо цвета поставить ссылку на цвет, и на старых версиях Андроида всё валится без внятных сообщений.
Dreddik
22.02.2022 17:55+1Щас бы в 2022 2 мегабайта экономить, и вместо использования общепринятых стандартов писать костыли и велосипеды
quaer
22.02.2022 18:20-1Не у всех мобильников гигабайт памяти на борту. Не радует терять деньги только из-за того, что у потенциального клиента старая версия Андроида или мало памяти на устройстве.
dimskiy
22.02.2022 19:30+1Если вы про устройства с Api < 21, то не представляю какой важности должен быть клиент чтобы мириться со всеми неудобствами minApi < 21. Одна работа с тенями чего стоит :/
quaer
22.02.2022 19:39-1Когда приложение это не очередная развлекаловка, клиентов не много и каждый важен. Тени далеко не в каждом приложении важны. Они конечно делают приложение модным, но этот материал дизайн, где элементы управления трудно отличить от обычных надписей, с его огромными отступами, порядком затрудняет разработку интерфейсов и взаимодействие с приложением.
dimskiy
22.02.2022 23:29+1Я, может, тайны и не открою… но интерфейс мобильного приложения - это основа коммерческого успеха. «Коряво, зато кнопки большие» прокатит в корпоративной среде, где платит не тот кто пользуется ;)
Neikist
23.02.2022 00:47У нас в планах возможно выпустить версию облегченную. Ибо очень много читалок не то что на четверке, но и на 2.3. Впрочем не факт. Возможно вообще в свободное от работы время сам облегченную версию набросаю.
grishkaa
23.02.2022 02:55Да я в общем-то уже это сделал. Только это наоборот, кастомные androidx вьюшки для 21+, с вызовами *Compat заменёнными на системные.
grishkaa
23.02.2022 02:59Developer experience для меня вообще ничего не значит. Если можно сэкономить 2 мегабайта — надо сэкономить, у меня такой вопрос даже не стоит. А если что-то является общепринятым стандартом, это ещё не значит, что это что-то хорошее. Сайты вон нынче на реакте пишут, это тоже «общепринятый стандарт». На M1 Max не лагают хотя бы. Пока что.
DolgopolovDenis Автор
22.02.2022 10:18+2думаю, основную выгоду от этих абстракций можно получить на крупных проектах с множеством разработчиков
то есть их основная цель - не дать каждому разработчику писать своё решение на каждый процесс
например, flow - казалось бы, напиши свои коллбеки на корутинах, пропиши сценарии переполнения и готово...
но когда я вижу у кого-то стандартный StateFlow - я сразу уверен, как оно работает и используется в проекте
когда я вижу кастомные SingleValueAnySubscribersDeleteIfNoSubsCallback, мне нужно потратить время, чтобы поверить в логику его работы
zagayevskiy
22.02.2022 12:16+2Hilt это не замена даггеру. Это упрощённая, урезанная надстройка. Перечислены множество "плюсов", которые сводятся к тому, что надо писать чуточку меньше кода(создание скоупов? серьёзно? в одну строку делается).
А про минусы ни слова. Компонентов(именно классов компонентов) ограниченное количество(можно создавать свои, но тогда весь смысл уменьшения количества кода теряется). Скоупов тоже ограниченное количество(по количеству компонентов). Теперь всё, что есть в скоупе фрагмента, доступно во всех фрагментах. Другими инстансами, да, что тоже может фрустрировать неофита.
Разделение на гредл-модули хромает. По сути хилт будет использоваться только в одном, главном модуле, а в остальных — будьте добры, чистый даггер.На мой взгляд, хилт — это попытка гугла подсадить всех-всех начинающих разработчиков на хоть какой-нибудь DI. Чтобы было. Для серьёзной разработки оно не подходит. Если модный == делает первые шажки, то конечно да, оно должно быть в подобных списках.
massivemadness
23.02.2022 14:36Разделение на гредл-модули хромает. По сути хилт будет использоваться только в одном, главном модуле, а в остальных — будьте добры, чистый даггер.
Звучит будто вы с хилтом никогда не работали, все там отлично с многомодульностью, нужно только плагин в feature-модули подключить. А вот с dynamic features тут да, есть к чему стремиться
zagayevskiy
23.02.2022 15:52Там всё построено на сабкомпонентах. В большом приложении монолитный граф это путь в никуда, пока они не сделали возможность разбить граф на части, "отлично с многомодульностью" это назвать нельзя.
zagayevskiy
22.02.2022 12:19+1Flow (StateFlow, SharedFlow...) — асинхронных способ передачи данных по подписочной модели. По принципу Flow — это LiveData с кучей настроек
Словил фейспалм. По принципу, Flow — это реактивный стрим данных, а никакая не сраная лайфдата. State/SharedFlow это реализация горячих стримов. А то выглядит так, будто PublishSubject изучил, подписался на него, и сидишь довольный.
dimskiy
По композ вы очень поверхностно прошлись. Основная плюшка - функциональный подход к формированию виджетов, использование иммутабельного состояния для обновления всех виджетов экрана. Раньше для этого создавали и парсили ViewState на базе дата-класса, теперь же этого делать не надо. Но заодно завезли довольно медленный и глючный рендеринг превью, так что удовольствия от процесса имхо пока не много. А итоговый код выглядит нагромождением вложений, даже если дробить на функции. Ну и еще есть правила написания таких функций, чтобы не терялся смысл.
В общем, тут все много глубже простого «избавились от xml и id”
Кстати, на месте новичка я бы не торопился учить композ - оно дойдет до хоть какой-то массовости не через год, и может даже не через 2. Как пример - флаттер. Сказки про него рассказывают уже года 4 изо всех блогов, а популярен массово он стал недавно. И в основном в аутсорсе, по понятным причинам.
DolgopolovDenis Автор
в целом согласен
но хотелось бы уточнить - и остальные технологии, описанные выше, совсем не то, с чего стоит начинать
о них стоит задумываться как раз в тот момент, когда всё неплохо работает на простых "fragment (xml) + live data + viewmodel + менеджеринг многопоточности" и уже хочется ускорить процесс разработки/попробовать что-то новое
Dreddik
Статья в принципе поверхностная, не совсем понимаю, почему вы выделили именно Compose. Тут про каждую технологию по отдельной статье можно написать
dimskiy
Потому что если проходиться по каждому пункту - будет отдельная статья в формате комментария