Главная » Хабрахабр » [Из песочницы] Модульная разработка Android приложений

[Из песочницы] Модульная разработка Android приложений

image

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

  • Модули в проекте, которые часто встречаются. Например, кастомные View
  • Когда существующий API неудобный или не позволяет сделать то, что задумали — создаем расширение для этого API

Все наши продукты – классифайды про автомобили, недвижимость и прочие товары. Чаще всего все проблемы были решены задолго до нас, но в нашем случае нужно было вынести часть слоя бизнес-логики и фактически весь слой, отвечающий за данные в 3 наших основных продукта объединенной компании Колёса Крыша Маркет. К тому же, это облегчило нашу работу. Поэтому нами, разработчиками, было решили написать одно решение для всех продуктов компании.

Попробовали git submodule

Если кратко объяснить его работу, то к git repository вы прикрепляете ссылку на другой git repository, который должен автоматически клонироваться вместе с родительским. Самое простое решение — использовать git submodule. Казалось бы все просто: у нас есть несколько git repository, где хранятся все наши модульные библиотеки и нужно всего лишь указать его в git submodule.

При обновлении через команду git submodule update стираются изменения в submodule, merge не происходит. Но как быть с версиями? Вместо этого стоит разрабатывать модули в виде библиотек с jar файлом или Android Archive (aar). Вам придется постоянно обновляться, когда другой разработчик вносит изменение в данном submodule. По факту, в этих архивах содержатся те же самые файлы, которые могли быть в git submodule, но теперь есть более понятное версионирование вместо истории commit или tag.

Осторожно, не все можно публиковать

Более того, не будет удобно остальным разработчикам, если в библиотеке будет содержаться код, относящийся к конкретной компании. При публикации библиотек стоить учесть, что они не должны содержать конфиденциальные данные компании. Есть множество open source решений, но мы используем JFrog Artifactory. Следовательно, нам нужен закрытый artifactory для хранения библиотек в закрытом доступе.

В таком случае вас ждет светлая дорога в мир open source проектов. А если можно публиковать? Достаточно просто найти открытые web серверы, которые поддерживают gradle, чтобы размещаемые jar и aar файлы подтягивались через dependency в ваших проектах.

Итак, начинаем создавать модуль



Начинается все просто — заходим в File > New > New Module…
Название библиотеки, которое укажете в этом окне, станет названием бинарника вашей библиотеки.

Если к прилагаемому коду будете писать тесты, остальным членам команды будет понятно, как вашим модулем пользоваться. Создав модуль можете приступить к написанию кода. Удобнее, когда вам нужно предварительно протестировать код перед публикацией в artifactory. Еще лучше, если создадите новый sample app module, который работает исключительно с вашим модулем для демонстрации на реальных устройствах. В примерах я буду указывать librarymodule в качестве названия модуля. Для этого достаточно указать зависимость в build.gradle.

# /sample-app
dependencies { implementation project(":librarymodule")
}

Настраиваем gradle для публикации в artifactory

Возьмем build скрипт от Chris Banes: Gradle скрипт для загрузки артифактов в Maven repositories

Основные настройки абсолютно идентичны: в каждом модуле, который нужно публиковать, вызываем gradle script файл из файла build.gradle модулей и создаем gradle.properties, где будет лежать конфигурационная информация для публикации. Конкретно в его случае описывается процесс в maven repository для публичной публикации. Нас интересует возможность публиковать в приватном artifactory

# {project}/build.gradle
RELEASE_REPOSITORY_URL={artifactory_url}/release-modules
SNAPSHOT_REPOSITORY_URL={artifactory_url}/snapshot-modules

Нам необходимо добавить 2 папки для публикации в artifactory: одну для официального релиза и snapshot для тестовых сборок модулей.

В тестовой сборке укажем SNAPSHOT в VERSION_NAME.
Когда у нас наконец-то настроен конфигурационный файл gradle.properties, мы готовы сделать первую публикацию библиотек в artifactory. Затем выполним команду:

./gradlew clean build sdk:uploadArchives

Настройка CI окружения

В завершениb осталось настроить CI окружение, чтобы мы могли встроить публикацию в наш процесс разработки.
Мы хотим, чтобы только CI мог публиковать в release artifactory, а для остальных добавим свободный доступ на чтение и запись в snapshot. Нам удалось вручную опубликовать модули в наш приватный artifactory. Пропишем {%username%} и {%password%} для доступа при публикации в artifactory. Поэтому внесем изменения в корневом файле gradle.properties, который обычно лежит в ~/.gradle/gradle.properties. Таким образом у нас будет настроен уровень доступа, без внесения изменений в .gitignore.

// ~/.gradle/gradle.properties
artifactory_username=login
artifactory_password=password

В список задач сборок добавляем запуск тестов, если у нас в модуле они есть. Добавляем trigger на ветку master, чтобы при merge у нас собралась сборка для публикации в release artifactory. Хорошо будет ещё настроить auto increment версии.

# Checkout git repository with modules
# Запускаем тест
./gradlew test
# Собираем архив для публикации
./gradlew librarymodule:build
# Публикация в artifactory
./gradlew libarrymodule:uploadArchives

Используем модуль в продукте

Но погодите, нам же нужно добавить еще и url к нашему artifactory, ведь они недоступны в типичном repository как maven Как только CI соберет сборку и зальет ее в artifactory, в проекте можно добавить зависимость этого модуля.

# {project}/build.gradle
allprojects { repositories { maven { url artifactory_url/release-modules } maven { url {artifactory_url}/snapshot-modules } }
}

Теперь мы можем использовать его в проекте.

# {project}/app/build.gradle
dependencies { implementation ‘kz.kolesa-team: librarymodule:1.0.0’
}

С чем мы столкнулись

Оказалось, что для этого нужно добавить gradle задачу с Dokka. При подключении Kotlin в наши модули документация для Kotlin файлов не подтягивается.

В процессе разработки модуля обязали указывать постфикс с идентификатором ticket из Jira. Если несколько разработчиков указывали идентичные версии для библиотек при публикации, то, естественно, актуальной версией модели оказывалась последняя публикация. 0. Получается что-то вроде 1. 1-AAS-1-SNAPSHOT.

Что в итоге получилось

Мы держали каждый модуль в отдельном git repository. Со временем у нас возросло количество модулей. В итоге получилось, что для выполнения одной задачи, необходимо было создавать PR в каждом git repository. Множество git repository создает большое количество неудобств в процессе разработки, если модуль имеет зависимость от других модулей. Поэтому, использовать один git repository для всех модулей на практике оказалось удобнее всего. Не совсем ясно, в каком порядке их нужно тестировать, не учитывая еще постоянное изменение PR, если в одном из PR внесли правки.

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

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


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[Из песочницы] Корпоративная печать, follow me, secure print

Добрый день, уважаемые коллеги. Немного о себе Позвольте представиться, меня зовут Алексей. Работаю в сфере IT вот уже более 15 лет и прошел путь от помощника Админа до менеджера в довольно крупной международной кампании. С недавних пор я осознал, что ...

Дайджест интересных материалов для мобильного разработчика #258 (18 июня — 24 июня)

В новом дайджесте рассказываем про быстрые команды Siri и заработок своим умом, дополненную реальность для музеев и дизайн для финтеха, снова про поиск работы и закат React Native, PWA и даже то, как не застрять в обучении. Подключайтесь! В своих ...