Обзор сборки Gradle,Обзор сборки Gradle

Приложения 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 Build» .

Конфигурационные DSL

Gradle использует доменно-ориентированный язык (DSL) для настройки сборок. Этот декларативный подход фокусируется на указании ваших данных, а не на написании пошаговых (императивных) инструкций.

DSL пытаются облегчить участие в проекте всем, экспертам в предметной области и программистам, определяя небольшой язык, который представляет данные более естественным образом. Плагины Gradle могут расширять DSL для настройки данных, необходимых для их задач.

Например, настройка Android-части вашей сборки может выглядеть так:

Котлин

android {
    namespace = "com.example.app"
    compileSdk = 34
    // ...

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 34
        // ...
    }
}

классный

android {
    namespace 'com.example.myapplication'
    compileSdk 34
    // ...

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 24
        // ...
    }
}

За кулисами код DSL похож на:

fun Project.android(configure: ApplicationExtension.() -> Unit) {
    ...
}

interface ApplicationExtension {
    var compileSdk: Int
    var namespace: String?

    val defaultConfig: DefaultConfig

    fun defaultConfig(configure: DefaultConfig.() -> Unit) {
        ...
    }
}

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

Внешние зависимости

Система сборки Maven представила спецификацию зависимостей , систему хранения и управления. Библиотеки хранятся в репозиториях (серверах или каталогах) с метаданными, включая их версию и зависимости от других библиотек. Вы указываете, в каких репозиториях выполнять поиск, версии зависимостей, которые хотите использовать, и система сборки загружает их во время сборки.

Артефакты Maven идентифицируются по имени группы (компания, разработчик и т. д.), имени артефакта (название библиотеки) и версии этого артефакта. Обычно это представляется как group:artifact:version .

Такой подход значительно улучшает управление сборкой. Такие репозитории часто можно услышать под названием «репозитории Maven», но все дело в том, как артефакты упаковываются и публикуются. Эти репозитории и метаданные повторно использовались в нескольких системах сборки, включая Gradle (и Gradle может публиковать данные в этих репозиториях). Публичные репозитории позволяют использовать их всем, а репозитории компаний хранят внутренние зависимости внутри компании.

Вы также можете разделить свой проект на подпроекты (также известные как «модули» в Android Studio), которые также можно использовать в качестве зависимостей. Каждый подпроект создает выходные данные (например, jar-файлы), которые могут использоваться подпроектами или вашим проектом верхнего уровня. Это может сократить время сборки за счет выделения частей, которые необходимо перестроить, а также за счет лучшего разделения обязанностей в приложении.

Мы более подробно рассмотрим, как указывать зависимости, в разделе «Добавление зависимостей сборки» .

Варианты сборки

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

Типы сборок различаются заявленными параметрами сборки. По умолчанию AGP устанавливает типы сборки «релиз» и «отладка», но вы можете настроить их и добавить больше (возможно, для промежуточного или внутреннего тестирования).

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

Сборка выпуска оптимизирует приложение, подписывает его ключом выпуска и защищает установленные файлы приложения.

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

AGP создает варианты для каждой комбинации типа сборки и разновидности продукта. Если вы не определите варианты, варианты будут названы в честь типов сборки. Если вы определите оба варианта, вариант будет называться <flavor><Buildtype> . Например, для типов сборки release и debug , а также для версий demo и full AGP создаст варианты:

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

Следующие шаги

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

,

Приложения 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 Build» .

Конфигурационные DSL

Gradle использует доменно-ориентированный язык (DSL) для настройки сборок. Этот декларативный подход фокусируется на указании ваших данных, а не на написании пошаговых (императивных) инструкций.

DSL пытаются облегчить участие в проекте всем, экспертам в предметной области и программистам, определяя небольшой язык, который представляет данные более естественным образом. Плагины Gradle могут расширять DSL для настройки данных, необходимых для их задач.

Например, настройка Android-части вашей сборки может выглядеть так:

Котлин

android {
    namespace = "com.example.app"
    compileSdk = 34
    // ...

    defaultConfig {
        applicationId = "com.example.app"
        minSdk = 34
        // ...
    }
}

классный

android {
    namespace 'com.example.myapplication'
    compileSdk 34
    // ...

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdk 24
        // ...
    }
}

За кулисами код DSL похож на:

fun Project.android(configure: ApplicationExtension.() -> Unit) {
    ...
}

interface ApplicationExtension {
    var compileSdk: Int
    var namespace: String?

    val defaultConfig: DefaultConfig

    fun defaultConfig(configure: DefaultConfig.() -> Unit) {
        ...
    }
}

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

Внешние зависимости

Система сборки Maven представила спецификацию зависимостей , систему хранения и управления. Библиотеки хранятся в репозиториях (серверах или каталогах) с метаданными, включая их версию и зависимости от других библиотек. Вы указываете, в каких репозиториях выполнять поиск, версии зависимостей, которые хотите использовать, и система сборки загружает их во время сборки.

Артефакты Maven идентифицируются по имени группы (компания, разработчик и т. д.), имени артефакта (название библиотеки) и версии этого артефакта. Обычно это представляется как group:artifact:version .

Такой подход значительно улучшает управление сборкой. Такие репозитории часто можно услышать под названием «репозитории Maven», но все дело в том, как артефакты упаковываются и публикуются. Эти репозитории и метаданные повторно использовались в нескольких системах сборки, включая Gradle (и Gradle может публиковать данные в этих репозиториях). Публичные репозитории позволяют использовать их всем, а репозитории компаний хранят внутренние зависимости внутри компании.

Вы также можете разделить свой проект на подпроекты (также известные как «модули» в Android Studio), которые также можно использовать в качестве зависимостей. Каждый подпроект создает выходные данные (например, jar-файлы), которые могут использоваться подпроектами или вашим проектом верхнего уровня. Это может сократить время сборки за счет выделения частей, которые необходимо перестроить, а также за счет лучшего разделения обязанностей в приложении.

Мы более подробно рассмотрим, как указывать зависимости, в разделе «Добавление зависимостей сборки» .

Варианты сборки

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

Типы сборок различаются заявленными параметрами сборки. По умолчанию AGP устанавливает типы сборки «релиз» и «отладка», но вы можете настроить их и добавить больше (возможно, для промежуточного или внутреннего тестирования).

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

Сборка выпуска оптимизирует приложение, подписывает его ключом выпуска и защищает установленные файлы приложения.

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

AGP создает варианты для каждой комбинации типа сборки и разновидности продукта. Если вы не определите варианты, варианты будут названы в честь типов сборки. Если вы определите оба варианта, вариант будет называться <flavor><Buildtype> . Например, с типами сборки release и debug , а также с вариантами demo и full AGP создаст варианты:

  • demoRelease
  • demoDebug
  • fullRelease
  • fullDebug

Следующие шаги

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