Наш опыт внедрения Compose в большой проект

Maxim
Kolesa Group
Published in
7 min readOct 26, 2023

Меня зовут Максим Рыбалов, я Android-разработчик в Kolesa Group. Расскажу, как мы постепенно внедрили в приложение Kolesa.kz новый инструмент от Google для разработки интерфейсов — Jetpack Compose.

Во многих командах понимают, что это перспективная технология. Но начать использовать Compose мешает нехватка знаний и опыта.

В этой статье расскажу:

  • Как мы внедрили Compose в большой проект и ничего не сломали;
  • Что помогло команде разобраться с этой технологией.
Максим Рыбалов

Jetpack Compose — это рекомендуемый Google набор инструментов для создания пользовательского интерфейса. Есть вероятность, что через несколько лет эта технология заместит XML. Поэтому команде Android-разработки нужно прокачивать экспертизу уже сейчас.

Плюсы и минусы Jetpack Compose

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

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

Мы не хотели играть в новые технологии. У Compose есть объективные плюсы:

  1. Декларативный UI. Даёт сконцентрироваться на том, что должно быть отражено, а не как. Это делает код более читаемым, компактным и понятным.
  2. Гибкость и модульность. Упрощает создание и настройку компонентов пользовательского интерфейса для более лёгкого масштабирования, переиспользования и обслуживания кода.
  3. Интерактивность. Предлагает удобный инструментарий для работы с анимацией.
  4. Поддержка со стороны разработчиков ОС. Они рекомендуют использовать Compose в Android-разработке и будут поддерживать эту технологию в будущем.
  5. Быстрое превью. Показывает изменения в реальном времени.
  6. Расширение стека. Позволяет заинтересовать команду и в будущем нанимать скилловых специалистов.

Минусы Compose:

  1. Декларативный UI. Отличная штука, но сначала надо привыкнуть к ней и научиться так работать.
  2. Нестабильность. Технология всё ещё новая.
  3. Зависимость от поддержки. Любая технология, которую вы не контролируете, влияет на ваш продукт.
  4. Отсутствие компонентов. Некоторых компонентов пока нет, или они в альфа/бета-версии.

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

Мы поняли, что время сыграет нам на руку: постепенно Compose усовершенствуется, а XML будет использоваться всё меньше. Команда Android-разработки должна развиваться в направлении, которое задаёт Google. Значит, в долгосрочной перспективе освоение Compose не только важно для нас, но и выгодно компании.

В Kolesa App множество экранов, каждый содержит уникальную фичу и анимацию

Возник вопрос: с чего начать? Сразу начинать писать новые фичи на Compose — рискованно, есть риск создать баги и неоптимизированный интерфейс. К тому же в нашей немаленькой команде никто не имел опыта работы с Compose.

Как построить процесс разработки?

У нас было три условия:

  1. Время — деньги. Нужно найти способ практиковаться без отрыва от работы, прямо на наших продуктах.
  2. Научиться работать с Compose должна вся команда.
  3. Нельзя нанести ущерб пользователям приложения.

В итоге мы продумали плавный процесс перехода с XML на Compose, который устроил и разработку, и бизнес.

Начали с изменений на non-critical экранах

Это экраны, которые пользователь либо не видит, или открывает крайне редко. Вносить изменения здесь безопасно — в случае ошибки лишь малая часть пользователей столкнётся с трудностями.

Переход с XML на Compose проходил плавно. Начали с тех экранов, которые пользователь не видит. Постепенно перешли на экраны, которые видит пользователь, например «О приложении». В таких случаях вводили новый вариант с помощью А/B-тестов. На случай поломки у нас был экспериментальный вариант.

Эти экраны находятся в глубине приложения

Использовали Compose для новых компонентов в дизайн-системе

Крутой способ наработать навыки создания Compose-элементов — реализовать компонент с нуля.

Например, нам дали задачу создать вот такую кнопку:

У кнопки могут быть разные состояния, цвета и контент

Мы взяли стандартный элемент из библиотеки Compose — Button. Понадобилось несколько изменений кода под наши нужды, поэтому мы написали свою реализацию базовой кнопки — CustomButton. Далее прописали DefaultButton и объявили в этом компоненте логику всех кнопок в нашем приложении.

Здесь объявили дефолтную логику для всех кнопок в приложении
Внутри DefaultButton вызов передаётся в CustomButton

Внутрь пробросили ButtonContent — информацию о том, какой контент содержится в кнопке.

Информация ButtonContent соотносится с перечнем состояний кнопки

ButtonState — информация о состоянии кнопки. В нашем случае это три варианта — Normal, Disabled и Loading.

А здесь — набор цветов для конкретного состояния кнопки:

Теперь, если нам нужна конкретная реализация кнопки — например, красная или синяя с иконкой — вот как она будет выглядеть:

Создаём Composable функцию BlueButton, внутри используем DefaultButton и передаём состояние кнопки с соответствующим набором цветов.

Теперь, если мы хотим где-то использовать BlueButton, то мы просто делаем так:

Если в нашей кнопке нам понадобится любая иконка, то в качестве ButtonContent указываем TextAndIcon. Аналогично и для любого другого контента.

В итоге у нас получилась такая иерархия классов кнопок:

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

Переписывать все элементы, уже созданные с помощью XML, не нужно. Мы можем прямо в XML вызвать BlueButtonView, и это будет прекрасно работать.

Сделали мы это при помощи AbstractComposeView. Он служит мостиком между классической системой Android Views и Jetpack Compose. Это абстрактный класс, который позволяет интегрировать контент, написанный с использованием Compose, в традиционное дерево представлений Android (View).

Вот как это реализуется у нас:

Есть ButtonView, он наследуется у AbstractComposeView. В этом случае вы обязаны заоверрайдить метод Content. В нём мы передаём вызов ButtonComponent — абстрактную функцию нашего абстрактного класса.

Для реализации BlueButtonView создаём этот класс, наследуем его от ButtonView и оверрайдим метод ButtonComponent. Внутри делегируем вызов компоненту BlueButton, написанный нами на Compose.

Реализация BlueButtonView

Теперь в иерархии кнопок появился вариант для реализации их XML-вариантов:

Со временем взялись за продуктовые экраны

Компетенция разработчиков росла. Ребята поопытнее, поработав с non-critical экранами и компонентами, стали пилить несложные продуктовые экраны. Часть приложения, с которой множество пользователей взаимодействуют каждый день, требует более ответственного отношения.

Вот пример такого экрана:

Состояние экрана без данных
Состояние экрана, когда в нём есть данные

Здесь нам понадобилось реализовать функцию refresh: пользователь тянет за шторку вниз, и содержание экрана обновляется. Эта фича появилась в более поздней версии Compose, и функционал успешно внедрили.

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

Научился — передай опыт коллеге

Итак, разработчики практикуются с Compose, когда переписывают non-critical экраны и создают новые элементы дизайн-системы. После этого опытные разработчики смело берутся за важные фичи и популярные экраны.

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

У нас сложилась такая система распределения задач:

1. Non-critical задачи даём тем, кто не работал с Compose вообще или работал меньше всех. Даже если здесь будут ошибки, это не критично.

2. Простые задачи назначаем на человека, у которого опыта с Compose меньше, чем у других ребят, но он не допустит критических багов.

3. Сложные, комплексные задачи даём более опытному специалисту. Он декомпозирует задачу и передаёт сабтаски менее опытным сотрудникам. Так можно задействовать несколько человек.

В команде kolesa.kz восемь Android-разработчиков. Спустя несколько месяцев такого подхода каждый из них успел поработать с Compose на «боевых» задачах, при этом не выкраивал дополнительное время на обучение.

Итоги и выводы

  • Элементы Сompose есть на 70% экранов приложения Kolesa.kz.
  • Благодаря плавному подходу не возникло ни одной поломки.
  • Вырос средний уровень технической подкованности команды.
  • Стек технологий стал более актуальным. Если в будущем Compose заменит XML, мы сможем нанимать скилловых специалистов и предлагать им интересные задачи.

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

Каждый из нас получил стимул изучить новую технологию. При этом соблюдаем баланс работы и отдыха, и остаётся «мыслетопливо» для сложных задач.

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

Дальше — больше. В планах:

  • Повышать экспертизу в Compose;
  • Пилить всё больше элементов на Compose разного уровня сложности;
  • Сделать крутую дизайн-систему.

--

--