Приложения для Android обычно создаются с использованием системы сборки Gradle . Прежде чем мы углубимся в детали настройки сборки, мы рассмотрим основные принципы, лежащие в её основе, чтобы вы могли видеть систему в целом.
Что такое сборка?
Система сборки преобразует ваш исходный код в исполняемое приложение. Сборка часто включает в себя множество инструментов для анализа, компиляции, компоновки и упаковки вашего приложения или библиотеки. Gradle использует подход, основанный на задачах, для организации и выполнения этих команд.
Задачи инкапсулируют команды, которые преобразуют свои входные данные в выходные. Плагины определяют задачи и их конфигурацию. Применение плагина к вашей сборке регистрирует его задачи и связывает их между собой, используя их входные и выходные данные. Например, применение плагина Android Gradle (AGP) к вашему файлу сборки зарегистрирует все задачи, необходимые для сборки APK или библиотеки Android. Плагин java-library позволяет собирать jar-файл из исходного кода Java. Аналогичные плагины существуют для Kotlin и других языков, но другие плагины предназначены для расширения существующих плагинов. Например, плагин protobuf предназначен для добавления поддержки protobuf к существующим плагинам, таким как AGP или java-library .
Gradle предпочитает соглашения конфигурации, поэтому плагины будут поставляться с хорошими значениями по умолчанию, но вы можете дополнительно настроить сборку с помощью декларативного предметно-ориентированного языка (DSL). DSL разработан таким образом, чтобы вы могли указать, что именно нужно собрать, а не как это сделать. Логика в плагинах управляет «как». Эта конфигурация задается в нескольких файлах сборки вашего проекта (и подпроектов).
Входными данными для задачи могут быть файлы и каталоги, а также другая информация, закодированная в виде типов Java (целые числа, строки или пользовательские классы). Выходными данными могут быть только каталоги или файлы, поскольку они должны быть записаны на диск. Соединение выходных данных одной задачи с входными данными другой задачи связывает задачи таким образом, что одна из них должна выполняться раньше другой.
Хотя Gradle поддерживает написание произвольного кода и объявлений задач в файлах сборки, это может затруднить понимание сборки инструментами и вашу поддержку. Например, вы можете писать тесты для кода внутри плагинов, но не в файлах сборки. Вместо этого следует ограничить логику сборки и объявления задач плагинами (которые определяете вы или кто-то другой) и указать, как вы хотите использовать эту логику, в файлах сборки.
Что происходит при выполнении команды сборки Gradle?
Сборка Gradle выполняется в три этапа. На каждом из этих этапов выполняются различные части кода, которые вы определяете в файлах сборки.
- На этапе инициализации определяются проекты и подпроекты, которые будут включены в сборку, а также настраиваются пути к классам, содержащие файлы сборки и применяемые плагины. На этом этапе основное внимание уделяется файлу настроек, где вы объявляете проекты для сборки и места, откуда будут загружаться плагины и библиотеки.
- В разделе конфигурации регистрируются задачи для каждого проекта, и выполняется файл сборки для применения спецификации сборки пользователя. Важно понимать, что ваш код конфигурации не будет иметь доступа к данным или файлам, созданным во время выполнения.
- На этапе выполнения происходит фактическая «сборка» вашего приложения. Результатом конфигурации является направленный ациклический граф (DAG) задач, представляющий все необходимые этапы сборки, запрошенные пользователем (задачи, указанные в командной строке или заданные по умолчанию в файлах сборки). Этот граф отображает взаимосвязь между задачами, либо явно указанную в объявлении задачи, либо основанную на ее входных и выходных данных. Если входные данные задачи являются выходными данными другой задачи, то она должна выполняться после этой задачи. На этом этапе выполняются устаревшие задачи в порядке, определенном в графе; если входные данные задачи не изменились с момента ее последнего выполнения, Gradle пропустит ее.
Для получения более подробной информации см. жизненный цикл сборки Gradle.
DSL-интерфейсы конфигурации
Gradle использует предметно-ориентированный язык (DSL) для настройки сборок. Этот декларативный подход фокусируется на указании ваших данных, а не на написании пошаговых (императивных) инструкций. Вы можете писать файлы сборки на Kotlin или Groovy, но мы настоятельно рекомендуем использовать Kotlin.
DSL призваны упростить участие в проекте для всех, от экспертов в предметной области до программистов, определяя небольшой язык, который представляет данные более естественным образом. Плагины Gradle могут расширять DSL для настройки данных, необходимых для их задач.
Например, настройка Android-части вашей сборки может выглядеть следующим образом:
Котлин
android { namespace = "com.example.app" compileSdk { version = release(36) { minorApiLevel = 1 } } // ... defaultConfig { applicationId = "com.example.app" minSdk { version = release(23) } targetSdk { version = release(36) } // ... } }
Классный
android { namespace = 'com.example.app' compileSdk { version = release(36) { minorApiLevel = 1 } } // ... defaultConfig { applicationId = 'com.example.app' minSdk { version = release(23) } targetSdk { version = release(36) } // ... } }
Внутри код DSL выглядит примерно так:
fun Project.android(configure: ApplicationExtension.() -> Unit) {
...
}
interface ApplicationExtension {
var namespace: String?
fun compileSdk(configure: CompileSdkSpec.() -> Unit) {
...
}
val defaultConfig: DefaultConfig
fun defaultConfig(configure: DefaultConfig.() -> Unit) {
...
}
}
Каждый блок в DSL представлен функцией, которая принимает лямбда-выражение для его настройки и свойство с тем же именем для доступа к нему. Это делает код в ваших файлах сборки более похожим на спецификацию данных.
Внешние зависимости
Система сборки Maven представила систему спецификации, хранения и управления зависимостями . Библиотеки хранятся в репозиториях (серверах или каталогах) с метаданными, включающими их версию и зависимости от других библиотек. Вы указываете, в каких репозиториях искать, версии зависимостей, которые хотите использовать, и система сборки загружает их во время сборки.
Артефакты Maven идентифицируются по названию группы (компания, разработчик и т. д.), названию артефакта (название библиотеки) и версии этого артефакта. Обычно это представляется в формате group:artifact:version .
Этот подход значительно улучшает управление сборкой. Такие репозитории часто называют «репозиториями Maven», но всё дело в способе упаковки и публикации артефактов. Эти репозитории и метаданные используются в нескольких системах сборки, включая Gradle (и Gradle может публиковать в эти репозитории). Публичные репозитории позволяют всем пользователям совместно использовать их, а корпоративные репозитории хранят внутренние зависимости внутри компании.
Вы также можете разделить свой проект на подпроекты (в Android Studio они называются «модулями»), которые также могут использоваться в качестве зависимостей. Каждый подпроект создает выходные файлы (например, JAR-файлы), которые могут использоваться подпроектами или вашим основным проектом. Это может сократить время сборки, поскольку позволяет изолировать части, требующие пересборки, а также лучше разделить обязанности в приложении.
Мы подробнее рассмотрим, как указывать зависимости в разделе «Добавить зависимости сборки» .
Варианты сборки
При создании Android-приложения обычно требуется создать несколько вариантов . Варианты содержат разный код или создаются с различными параметрами и состоят из типов сборки и вариантов продукта.
Типы сборки различаются заявленными параметрами сборки. По умолчанию AGP устанавливает типы сборки «release» и «debug», но вы можете изменить их и добавить другие (например, для промежуточного тестирования или внутренней проверки).
Отладочная сборка не минимизирует и не обфусцирует ваше приложение, ускоряя его сборку и сохраняя все символы в исходном виде. Она также помечает приложение как «подлежащее отладке», подписывая его универсальным ключом отладки и предоставляя доступ к установленным на устройстве файлам приложения. Это позволяет просматривать сохраненные данные в файлах и базах данных во время работы приложения.
Сборка для выпуска оптимизирует приложение, подписывает его вашим ключом выпуска и защищает файлы установленного приложения.
Используя варианты продукта , вы можете изменять включенные варианты исходного кода и зависимостей для приложения. Например, вы можете создать варианты «демо» и «полная версия» для своего приложения, или, возможно, «бесплатная» и «платная» версии. Вы пишете свой общий исходный код в каталоге «основного» набора исходных кодов и переопределяете или добавляете исходный код в наборе исходных кодов, названном в честь варианта.
AGP создает варианты для каждой комбинации типа сборки и варианта продукта. Если вы не определяете варианты, варианты именуются в соответствии с типами сборки. Если вы определяете оба типа, вариант именуется как <flavor><Buildtype> . Например, при типах сборки release и debug и вариантах demo и full , AGP создаст следующие варианты:
-
demoRelease -
demoDebug -
fullRelease -
fullDebug
Следующие шаги
Теперь, когда вы ознакомились с концепциями сборки, взгляните на структуру сборки Android в вашем проекте.