Введение
В этой статье разберем все файлы проекта, в названиях которых встречается слово gradle. Понимание структуры проекта – шаг к уверенному пониманию подкапотных процессов и +10 к уверенности на собеседовании.
Что такое gradle в Android проекте
Итак. В иерархии файлов можно наблюдать множество файлов и папок с названием gradle.
Что такое gradle? Это система для сборки наших проектов.
Зачем она нужна? Ну начнем с того, что конечная цель нашей работы (программирования) — это APK файл, который устанавливается на устройство.
Это файл в котором упакованы:
- Код приложения, в том числе обсуждаемый выше.
- Ресурсы в нужном предобработанном виде.
- А также конфигурационные файлы.
Все это подписано специальной подписью, чтобы удостоверить факт владения нами этой APK’шкой. Это конечный результат нашей работы.
И чтобы собрать этот файл нужно использовать с десяток разнообразных утилит. Во-первых это сам компилятор, который компилирует Kotlin файлы в байт код. Во-вторых это различные оптимизаторы и обфускаторы, которые удаляют какие-то неиспользуемые фрагменты кода. Или которые изменяют реальные названия классов/переменных, чтобы тем, кто решит разобраться в логике нашего приложения было сложнее это сделать. Кроме того gradle еще занимается тем, что преобразует ресурсы. Занимается их “шринкингом” — оптимизацией, уменьшением.
Если в проекте используются градл-плагины, а они у нас используются, в частности androidApplication и kotlinAndroid (о них будет ниже). Gradle также осуществляет запуск этих плагинов, например, чтобы сделать какие-то дополнительные преобразования. Кто проходил с нами практику по KotlinSprint, помнит, что в курсовом проекте мы использовали kotlinx serialization. Штуку, которая позволяла в автоматическом режиме преобразовывать файлы в JSON объекты и обратно. Так вот обработкой этих аннотаций также занимается gradle плагин — kotlinx serialization.
По итогу вот ВСЕМ этим занимается gradle. Он позволяет взять все утилиты, которые нужны для сборки проекта и вызвать их в правильной последовательности с правильными параметрами.
Порядок тут действительно важен, потому, что, например нет смысла компилировать Котлин код полностью в байт код, если мы еще, например, не сгенерировали классы для сериализации и десериализации JSON.
Конфигурация gradle
Каталог .gradle
Хорошо. Папка .gradle. Вообще в операционных системах папки с точкой в начале являются скрытыми. То есть не предназначены для пользовательских глаз. В этой папке хранится определенная версия gradle, его кэш да и в принципе тут больше ничего интересного. Это автоматически сгенерированная папка и мы туда обычно не ходим.
Разница между build.gradle и build.gradle.kts.
Gradle конфигурируется несколькими файлами. Но прежде чем мы по ним пройдемся, нужно кое-что уточнить. Обратите внимание — вы можете видеть файлы с похожим названием, но разным расширением build.gradle и build.gradle.kts. А также можно встретить settings.gradle и settings.gradle.kts.
Постараюсь объяснить коротко, чтобы не образовалось каши в голове. Итак, эти парные файлы выполняют одну и ту же функцию – хранят глобальные настройки проекта. Но build.gradle и settings.gradle написаны на Groovy – это динамический язык используемый на JVM, но с возможностями Python и Ruby. Исторически сложилось, что в Андройд проектах на нем пишутся конфигурационные файлы.
Файлы с расширением .kts — это сокращение от Kotlin Script. Конфиги пишутся с использованием Kotlin DSL – специальный набор инструментов и синтаксис на основе Kotlin.
Это относительно свежий подход. И сейчас происходит миграция c Groovy на Kotlin DSL. С версии Android Studio Giraffe все файлы настроек поставляются уже с расширением .kts. Об довольно доступно написано в гугл документации, ссылка на материал по миграции конфигурации: https://developer.android.com/build/m…
Это в принципе все, что достаточно понимать, чтобы различать такие файлы и не путаться между ними.
Итак, я создам новый проект в последней стабильной на сегодняшний день версии Android Studio и покажу как выглядят эти файлы из коробки во всех новых проектах.
settings.gradle.kts
Это общий файл настроек gradle проекта. Здесь как правило указывается имя проекта и перечисляются модули (или подпроекты), которые включены в этот проект. Крупные Android проекты обычно делятся на большое количество разных модулей со своей функциональностью. И все они перечисляются здесь. В нашем случае добавлен один модуль app — он отображается в иерархии файлов с иконкой квадратика на каталоге.
Здесь же указываются репозитории для плагинов. То есть те места, откуда плагины будут качаться.
pluginManagement — определяет, что все плагины, используемые в проекте будут качаться из данных репозиториев. Это про плагины.
dependencyResolutionManagement — конфигурирует эти репозитории и управляет стратегиями разрешения зависимостей, типа определения общих репозиториев, разрешением конфликтов и тд. То есть это больше про зависимости и их тонкие конфигурации.
Не переживайте, на начальном и даже среднем этапе обучения в это лезть скорее всего не придется. Пока воспринимайте бОльшую часть конфигурационных файлов в качестве экскурсии по Гигафабрике Маска. Только еще разрешается при этом есть и фотографировать.
gradle.properties
Следующий файл с конфигурацией gradle.properties. Это файл в котором в виде “ключ = значение” хранятся различные дополнительные параметры для gradle.
Например тут есть kotlin.code.style — при сборке проекта градл может проверять стиль кода и выкидывать различные предупреждения. Но как правило для проверки стиля используются дополнительные утилиты с гибко настраиваемыми правилами, например, Detect.
gradlew
Здесь есть еще вот такие два файла — gradlew и gradlew.bat. Это на самом деле просто два скрипта. Файл с расширением .bat делает запускаемый файл для Windows, второй файл для Linux и MacOS.
gradlew расшифровывается, как gradle wrapper. То есть “gradle обертка”. Это специальная штука, которая позволяет собирать проект, не устанавливая gradle вам в систему. Часто бывает, на компьютере на котором запускается сборка не установлен Gradle, или установлена несовместимая с проектом версия. Поэтому популярным приемом является использование врапперов. Gradlew — это по сути скрипт, который используя gradle-wrapper.properties скачивает нужную версию градла и применяет ее для сборки проекта. Этот процесс вы часто можете видеть при открытии нового или склонированного проекта.
Вот здесь, в файле gradle-wrapper.properties, указывается URL, откуда качается определенная версия gradle.
Студия использует gradlew неявно для вас, и пока вам не придется его использовать напрямую. Но если захотите выполнять градл таски через терминал, или настраиваете систему автоматической сборки приложения — gradlew упростит вам жизнь.
build.gradle.kts
Наконец нам еще интересен файл build.gradle.kts. Один файл находится в корне проекта, в котором указаны плагины, используемые в системе.
Причем обратите внимание на синтаксис. Плагин передается через функцию alias — это действительно функция, в ее декларацию можно провалиться и посмотреть.
Метод принимает параметр notation — конструкция с айдишником плагина и его точно указанной версией для скачивания. Нотэйшн в свою очередь хранится по пути libs.plugins и название плагина.
Провалимся в них и увидим, что это просто файл-хранилище версий. Вот тут указан id (то есть название) плагина, вот тут вынесена ссылка на переменную с версией.
Это сделано потому, что для разных плагинов из одного семейства может использоваться одна и та же версия.
Если навести на версию с подсветкой — можно обнаружить, что для определенного плагина доступно обновление.
Библиотеки развиваются, в них исправляются баги и добавляется функционал, тогда разработчик библиотеки повышает цифру и заливает свежую версию в сеть. Обновляйтесь с осторожностью, особенно мажорные версии и после синхронизации проверяйте работоспособность всех модулей. Ничего ли не отвалилось.
Второй файл находится в нашем единственном модуле. И вот этот файл содержит настройки, которые касаются непосредственно нашего приложения.
Что здесь перечислено:
- Список плагинов для этого подпроекта. Плагины, это градл скрипты осуществляющие дополнительную работу во время сборки, например есть плагин для отправки сборки в Google Play или неявно используемый нами android gradle plugin (он же AGP). Он содержит набор операций для подготовки и упаковки ресурсов нашего приложения, компилирования и оптимизации кода и финальной сборки APK (на самом деле там еще много чего, но это основное). Чуть подробнее про то, что это за плагины:
- com.android.application — базовый Android Gradle плагин для разработки Android приложений. Отвечает за методы компиляции проекта в исполняемый (машинный) код. Управляет ресурсами, упаковывает их в конечный APK или AppBundle файл.
- org.jetbrains.kotlin.android — плагин от JetBrains для поддержки языка Kotlin в проектах Android.
- Дальше идет конфигурация плагина Android (выше мы указали, что подключается плагин Android Application). Конфигурируем его при помощи функции android. Условно эта функция, которая принимает в параметры лямбду.
- namespace — пространство имен или уникальный package name проекта.compileSdk — версия Android SDK с которой будет именно скомпилирована сборка с помощью gradle. Если здесь поменять версию, например, на более раннюю, то увидим как в списке библиотек SDK тоже поменяло версию. И фичи Android, которые появились в более свежих версиях относительно указанной использовать уже не получится.defaultConfig — конфиг, который будет использоваться по умолчанию, но сверху мы можем переопределять какие-то параметры. То есть можно изменить applicationId или версию кода и это значение подтянется в финальный MergedManifest, который попадет в конечную APK.minSdk — уже рассматривалось ранее. Минимально поддерживаемая версия Android.targetSdk — та версия, для которой это приложение по сути ориентировано. Когда вы пишете код приложения, то ожидаете, что оно будет поддерживать определенный API. То есть в нем будут даны определенные функции, которые можно использовать.
- buildTypes — Это секция, которая позволяет настроить различные варианты сборки вашего приложения. Например, вы можете определить два разных «build type» — один для разработки (debug), который может содержать дополнительные отладочные инструменты, и другой для выпуска (release), который будет оптимизирован для конечного пользователя.
- compileOptions — Здесь можно настроить параметры компиляции приложения. Например, вы можете указать версию языка, которую вы хотите использовать, или установить разные флаги компилятора.
- kotlinOptions — Эта секция предназначена специально для настройки параметров компиляции Kotlin. Вы можете указать версию Kotlin, использовать какие-то специфические функции или настройки для компиляции Kotlin-кода вашего приложения.
- buildFeatures — Здесь вы можете включать или выключать различные функции Gradle и Android Studio, которые могут влиять на сборку вашего приложения. Например, в рабочем приложении мы включали возможность использования ViewBinding в проекте.
- Далее мы видим блок dependecies. Эта секция используется для определения библиотек и зависимостей, которые ваше приложение использует. Вы указываете здесь библиотеки, которые должны быть включены в ваш проект, и Gradle автоматически загрузит их из Интернета и подготовит для использованияу . Это могут быть нестандартные компоненты интерфейса, библиотеки для json-сериализации, для загрузки картинок и любые другие, расширяющие функционал нашего приложения. Про синтаксис обращения через libs я уже рассказал чуть ранее, здесь точно такой же принцип работы. Зачастую в проекте может быть много модулей и раньше приходилось редактировать версии в каждом файле отдельно. Для упрощения использовался собственный каталог версий. Это отдельный файл в котором перечислялись все зависимости, а в gradle конфигах используем только ссылки на них Это создавало некоторый хаос. Гугл решил организовать хранение зависимостей и создал отдельный каталог с версиями — очень классный подход. Тут есть два основных типа зависимостей:
implementation
иtestImplementation
/androidTestImplementation
.- implementation — Этот тип зависимости используется для библиотек и кода, которые должны быть включены в приложение при сборке (в его конечный APK или AppBundle файл). Эти библиотеки будут доступны в приложении во время выполнения. Например:
androidx.core:core-ktx
— Это библиотека AndroidX, предоставляющая расширения Kotlin для работы с основными компонентами Android, такими какView
иActivity
.
- testImplementation и androidTestImplementation — Эти типы зависимостей используются для тестирования приложения. Они не включаются в конечное приложение, а используются только при написании и запуске тестов. Примеры:
junit
— Это библиотека JUnit для написания юнит-тестов в Java/Kotlin.androidx.test.ext:junit
— Эта библиотека предоставляет инструменты для написания Android-тестов, использующих JUnit.androidx.test.espresso:espresso-core
— Espresso — это библиотека для написания функциональных тестов пользовательского интерфейса Android-приложений.
- implementation — Этот тип зависимости используется для библиотек и кода, которые должны быть включены в приложение при сборке (в его конечный APK или AppBundle файл). Эти библиотеки будут доступны в приложении во время выполнения. Например:
Конфигурационная папка .idea
Еще папка проекта содержит скрытую папку .idea, которая хранит настройки специфичные для Android Studio, такие как настройки автоформатирования, кэши, настройки системы хранения кода и прочее. Однако, в подавляющем большинстве случаев эти настройки студия может сгенерировать сама на основе gradle конфига, для этого достаточно нажать иконку Gradle и дождаться завершения индексации проекта.
Как правило папку .idea добавляют в .ginignore, так как ценного она особо не хранит. Чтобы когда через пару лет вы откроете свой исходный код, с меньшей вероятностью столкнуться с проблемой устаревшего конфига Android Studio.
Мы перечислили самое основное, что встречается в большинстве Android проектов. Также вы можете встретить в действующих проектах специфичные конфиги, например, для настройки CI/CD (это когда проект автоматический собирается при отправке кода), файлы конфигов detekt’а и lint — для тонкой настройки предупреждений о нарушений стиля кода.. и прочее.
Вы с этим обязательно разберетесь, скорее всего, постепенно накапливая насмотренность, за счет самостоятельного написания кода и изучения структур новых проектов. Ну а в следующих уроках двигаемся дальше по новым технологиям, постепенно накидывая мяса на наше учебное приложение.
Для тех, кто собрался стать Android-разработчиком
Пошаговая
схема
Описание процесса обучения от основ Kotlin до Android-разработчика
Бесплатные
уроки
Авторский бесплатный курс по основам языка программирования Kotlin
Обучающий
бот
Тренажер и самоучитель по Котлин – бесплатные тесты и практика