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

С другой - перечисленные технологии становятся новой реальностью. И теперь просто знать о мультипоточности, 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)


  1. dimskiy
    22.02.2022 00:04
    +3

    По композ вы очень поверхностно прошлись. Основная плюшка - функциональный подход к формированию виджетов, использование иммутабельного состояния для обновления всех виджетов экрана. Раньше для этого создавали и парсили ViewState на базе дата-класса, теперь же этого делать не надо. Но заодно завезли довольно медленный и глючный рендеринг превью, так что удовольствия от процесса имхо пока не много. А итоговый код выглядит нагромождением вложений, даже если дробить на функции. Ну и еще есть правила написания таких функций, чтобы не терялся смысл.

    В общем, тут все много глубже простого «избавились от xml и id”

    Кстати, на месте новичка я бы не торопился учить композ - оно дойдет до хоть какой-то массовости не через год, и может даже не через 2. Как пример - флаттер. Сказки про него рассказывают уже года 4 изо всех блогов, а популярен массово он стал недавно. И в основном в аутсорсе, по понятным причинам.


    1. DolgopolovDenis Автор
      22.02.2022 10:07

      в целом согласен

      но хотелось бы уточнить - и остальные технологии, описанные выше, совсем не то, с чего стоит начинать

      о них стоит задумываться как раз в тот момент, когда всё неплохо работает на простых "fragment (xml) + live data + viewmodel + менеджеринг многопоточности" и уже хочется ускорить процесс разработки/попробовать что-то новое


    1. Dreddik
      22.02.2022 11:24

      Статья в принципе поверхностная, не совсем понимаю, почему вы выделили именно Compose. Тут про каждую технологию по отдельной статье можно написать


      1. dimskiy
        22.02.2022 12:51

        Потому что если проходиться по каждому пункту - будет отдельная статья в формате комментария


  1. grishkaa
    22.02.2022 07:45
    +4

    Не надо становиться модным, надо становиться нормальным :)

    Даже если отбросить мою личную неприязнь к котлину, проблема использования модных гугловских абстракций поверх SDK в том, что они постоянно меняются и никогда не готовы. Одно уже задепрекейтили, а предлагаемая замена всё ещё в бете. Та же навигация — гугл уже, наверное, третье или четвёртое по счёту решение на эту тему представляет, я уже перестал за всем этим следить, просто написал свой простенький стек для системных фрагментов и пользуюсь им. Да, даже appcompat на самом деле не нужен.


    1. dimskiy
      22.02.2022 10:08

      Вы, мягко говоря, преувеличиваете. Та же nav library все та же как была, только обновляется регулярно. Не помню когда там были последний раз breaking changes :)

      Да, даже appcompat на самом деле не нужен.

      ????‍♂️

      Вы простите, но когда человек не занимается каким-то направлением разработки, то ему и не судить бы о его (направлении) специфике, верно?


      1. grishkaa
        22.02.2022 10:11
        +1

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


        1. dimskiy
          22.02.2022 12:50

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

          ps. Ни на что не намекаю, но можно и за 5 лет не продвинуться особо, я встречал такие примеры. Просто не будем гнуть пальцы ;)


          1. Neikist
            22.02.2022 13:15

            Вы и правда ни на что не намекаете. Григорий то человек известный в коммьюнити, хоть и взглядов придерживается не стандартных. Офф клиенты вк и телеги писал тех же.
            З.Ы. Сам придерживаюсь чего то среднего. С одной стороны современное коммьюнити чрезмерно упоролось абстракциями и «архитектурами», с другой писать на голой java и всюду вставлять проверки на версию SDK по мне тоже как то перебор.


            1. Dreddik
              23.02.2022 00:34

              Всем сердцем люблю Гришу, но зачастую сложно мириться с его хейтом "просто потому что".


      1. quaer
        22.02.2022 16:49

        Вдумайтесь - каждое приложение тащит за собой androidx. Хорошо хоть не целую ява-машину. Как пример, приложение без него - 200 кБ, с ним - 2 мб с лишним.

        И при этом полная мешанина в стилях, где теперь надо их менять для сходных стилей в разных неймспейсах, а стоит немного ошибться, например вместо цвета поставить ссылку на цвет, и на старых версиях Андроида всё валится без внятных сообщений.


        1. Dreddik
          22.02.2022 17:55
          +1

          Щас бы в 2022 2 мегабайта экономить, и вместо использования общепринятых стандартов писать костыли и велосипеды


          1. quaer
            22.02.2022 18:20
            -1

            Не у всех мобильников гигабайт памяти на борту. Не радует терять деньги только из-за того, что у потенциального клиента старая версия Андроида или мало памяти на устройстве.


            1. dimskiy
              22.02.2022 19:30
              +1

              Если вы про устройства с Api < 21, то не представляю какой важности должен быть клиент чтобы мириться со всеми неудобствами minApi < 21. Одна работа с тенями чего стоит :/


              1. quaer
                22.02.2022 19:39
                -1

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


                1. dimskiy
                  22.02.2022 23:29
                  +1

                  Я, может, тайны и не открою… но интерфейс мобильного приложения - это основа коммерческого успеха. «Коряво, зато кнопки большие» прокатит в корпоративной среде, где платит не тот кто пользуется ;)


              1. Neikist
                23.02.2022 00:47

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


                1. grishkaa
                  23.02.2022 02:55

                  Да я в общем-то уже это сделал. Только это наоборот, кастомные androidx вьюшки для 21+, с вызовами *Compat заменёнными на системные.


          1. grishkaa
            23.02.2022 02:59

            Developer experience для меня вообще ничего не значит. Если можно сэкономить 2 мегабайта — надо сэкономить, у меня такой вопрос даже не стоит. А если что-то является общепринятым стандартом, это ещё не значит, что это что-то хорошее. Сайты вон нынче на реакте пишут, это тоже «общепринятый стандарт». На M1 Max не лагают хотя бы. Пока что.


        1. grishkaa
          23.02.2022 03:00

          Хорошо хоть не целую ява-машину.
          Флаттер передаёт привет)))0


    1. DolgopolovDenis Автор
      22.02.2022 10:18
      +2

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

      то есть их основная цель - не дать каждому разработчику писать своё решение на каждый процесс

      например, flow - казалось бы, напиши свои коллбеки на корутинах, пропиши сценарии переполнения и готово...

      но когда я вижу у кого-то стандартный StateFlow - я сразу уверен, как оно работает и используется в проекте

      когда я вижу кастомные SingleValueAnySubscribersDeleteIfNoSubsCallback, мне нужно потратить время, чтобы поверить в логику его работы


      1. dimskiy
        22.02.2022 23:32
        +1

        Какие корутины, вы что! Хендлеры и луперы (привет, Яндекс). А еще лучше - голые Threads :)


        1. Neikist
          23.02.2022 00:48

          Иногда возникает желание упороться. Но потом понимаешь что это после тебя еще другим поддерживать…


  1. Dreddik
    22.02.2022 11:20
    -1

    MVI или MVVM тут уж кому как больше нравится


  1. zagayevskiy
    22.02.2022 12:16
    +2

    Hilt это не замена даггеру. Это упрощённая, урезанная надстройка. Перечислены множество "плюсов", которые сводятся к тому, что надо писать чуточку меньше кода(создание скоупов? серьёзно? в одну строку делается).
    А про минусы ни слова. Компонентов(именно классов компонентов) ограниченное количество(можно создавать свои, но тогда весь смысл уменьшения количества кода теряется). Скоупов тоже ограниченное количество(по количеству компонентов). Теперь всё, что есть в скоупе фрагмента, доступно во всех фрагментах. Другими инстансами, да, что тоже может фрустрировать неофита.
    Разделение на гредл-модули хромает. По сути хилт будет использоваться только в одном, главном модуле, а в остальных — будьте добры, чистый даггер.


    На мой взгляд, хилт — это попытка гугла подсадить всех-всех начинающих разработчиков на хоть какой-нибудь DI. Чтобы было. Для серьёзной разработки оно не подходит. Если модный == делает первые шажки, то конечно да, оно должно быть в подобных списках.


    1. massivemadness
      23.02.2022 14:36

      Разделение на гредл-модули хромает. По сути хилт будет использоваться только в одном, главном модуле, а в остальных — будьте добры, чистый даггер.

      Звучит будто вы с хилтом никогда не работали, все там отлично с многомодульностью, нужно только плагин в feature-модули подключить. А вот с dynamic features тут да, есть к чему стремиться


      1. zagayevskiy
        23.02.2022 15:52

        Там всё построено на сабкомпонентах. В большом приложении монолитный граф это путь в никуда, пока они не сделали возможность разбить граф на части, "отлично с многомодульностью" это назвать нельзя.


  1. zagayevskiy
    22.02.2022 12:19
    +1

    Flow (StateFlow, SharedFlow...) — асинхронных способ передачи данных по подписочной модели. По принципу Flow — это LiveData с кучей настроек

    Словил фейспалм. По принципу, Flow — это реактивный стрим данных, а никакая не сраная лайфдата. State/SharedFlow это реализация горячих стримов. А то выглядит так, будто PublishSubject изучил, подписался на него, и сидишь довольный.