⚠️ Работа с зависимостями в Gradle таит множество подводных камней:
- Откуда берётся зависимость?
- Какие транзитивные зависимости подтянутся вместе с ней?
- Как убедиться, что скачался именно тот артефакт, который вы ожидали?
Чтобы сборка была стабильной, безопасной и быстрой, стоит придерживаться ряда практик 👇
1️⃣ Используйте единый источник зависимостей
В больших компаниях принято разворачивать свой Nexus / Artifactory. Он проксирует остальные репозитории (MavenCentral, Google и др.), и для проекта остаётся один источник правды.
Это ускоряет сборку (репозиторий ближе и быстрее), а также защищает от случайного скачивания библиотек «из непонятного интернета».
2️⃣ Ограничивайте содержимое репозиториев
При подключении нескольких репозиториев стоит явно ограничить группы пакетов, которые могут из них подтягиваться.
Например, для Google Maven:
Так вы избежите ненужных запросов в «левые» репозитории.
3️⃣ Проверяйте скачанные артефакты
Gradle поддерживает dependency verification. Это позволяет проверить контрольные суммы загружаемых артефактов и защититься от подмены.
📖 Документация: Dependency Verification
Пример gradle/verification-metadata.xml:
4️⃣ Ограничивайте транзитивные зависимости
Любая библиотека подтягивает за собой десятки других. Чтобы не получить неожиданное поведение или небезопасные версии — используйте constraints:
А если нужно зафиксировать версии жёстко:
5️⃣ Анализируйте дерево зависимостей
Чтобы понять, кто и что тянет, используйте:
Это поможет отловить дубликаты и неожиданные версии.
6️⃣ Автоматизируйте обновления
Поддерживайте проект в актуальном состоянии:
🔄 используйте Gradle Versions Plugin, чтобы проверять обновления библиотек.
📝 заведите политику обновлений (например, обновлять минорные версии раз в месяц, а мажорные — отдельно и осознанно).
🔥 В итоге, хорошая стратегия работы с зависимостями — это баланс между удобством разработки и контролем. Чем больше проект и команда, тем жёстче стоит соблюдать правила.
#gradle #лучшиепрактики
- Откуда берётся зависимость?
- Какие транзитивные зависимости подтянутся вместе с ней?
- Как убедиться, что скачался именно тот артефакт, который вы ожидали?
Чтобы сборка была стабильной, безопасной и быстрой, стоит придерживаться ряда практик 👇
В больших компаниях принято разворачивать свой Nexus / Artifactory. Он проксирует остальные репозитории (MavenCentral, Google и др.), и для проекта остаётся один источник правды.
Это ускоряет сборку (репозиторий ближе и быстрее), а также защищает от случайного скачивания библиотек «из непонятного интернета».
При подключении нескольких репозиториев стоит явно ограничить группы пакетов, которые могут из них подтягиваться.
Например, для Google Maven:
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google {
mavenContent {
includeGroupAndSubgroups("androidx")
includeGroupAndSubgroups("com.android")
includeGroupAndSubgroups("com.google")
includeGroupAndSubgroups("org.chromium.net")
includeGroupAndSubgroups("com.crashlytics.sdk")
}
}
mavenCentral()
}
}
Так вы избежите ненужных запросов в «левые» репозитории.
Gradle поддерживает dependency verification. Это позволяет проверить контрольные суммы загружаемых артефактов и защититься от подмены.
📖 Документация: Dependency Verification
Пример gradle/verification-metadata.xml:
<verification-metadata>
<configuration>
<verify-metadata>true</verify-metadata>
<verify-signatures>false</verify-signatures>
</configuration>
<components>
<component group="org.apache.pdfbox" name="pdfbox" version="2.0.17">
<artifact name="pdfbox-2.0.17.jar">
<sha512 value="..." />
</artifact>
</component>
</components>
</verification-metadata>
Любая библиотека подтягивает за собой десятки других. Чтобы не получить неожиданное поведение или небезопасные версии — используйте constraints:
dependencies {
implementation("org.apache.httpcomponents:httpclient")
constraints {
implementation("org.apache.httpcomponents:httpclient:4.5.3") {
because("previous versions have a critical bug")
}
implementation("commons-codec:commons-codec:1.11") {
because("version 1.9 pulled from httpclient has issues")
}
}
}А если нужно зафиксировать версии жёстко:
configurations.all {
resolutionStrategy {
force("org.example:lib:1.2.3")
// Есть много других возможностей
}
}Чтобы понять, кто и что тянет, используйте:
./gradlew dependencies
./gradlew dependencyInsight --dependency okhttp --configuration releaseRuntimeClasspath
Это поможет отловить дубликаты и неожиданные версии.
Поддерживайте проект в актуальном состоянии:
🔄 используйте Gradle Versions Plugin, чтобы проверять обновления библиотек.
📝 заведите политику обновлений (например, обновлять минорные версии раз в месяц, а мажорные — отдельно и осознанно).
🔥 В итоге, хорошая стратегия работы с зависимостями — это баланс между удобством разработки и контролем. Чем больше проект и команда, тем жёстче стоит соблюдать правила.
#gradle #лучшиепрактики
Please open Telegram to view this post
VIEW IN TELEGRAM
🚀 Чтобы ускорить работу с Gradle рекомендую всем включить в настройках IDE параллельную работу синхронизации IDEA и Gradle проекта.
🐘 Что даёт включение «parallel fetching»
По умолчанию Gradle получает модели последовательно — по одному модулю за раз.
С включённой опцией IDE может запрашивать модели параллельно для нескольких модулей, что:
👉 ускоряет синхронизацию крупных многомодульных проектов;
👉 сокращает время обновления проекта после изменения Gradel build-файлов;
👉 лучше использует возможности CPU
#gradle #androidstudio #idea
По умолчанию Gradle получает модели последовательно — по одному модулю за раз.
С включённой опцией IDE может запрашивать модели параллельно для нескольких модулей, что:
👉 ускоряет синхронизацию крупных многомодульных проектов;
👉 сокращает время обновления проекта после изменения Gradel build-файлов;
👉 лучше использует возможности CPU
#gradle #androidstudio #idea
Please open Telegram to view this post
VIEW IN TELEGRAM
Не так давно разобрал как работает Swift для Android, но там совсем "на скорую руку" сделали интеграцию с Gradle билд системой.
Решил показать как будет сделать нормальный плагин по лучшим практикам Gradle. Демонстрация разработки в новом видео.
Если у вас есть проблемы с Boosty - пишите @ab_manager
#AndroidBroadcast #Gradle #Swift #AndroidDev
Please open Telegram to view this post
VIEW IN TELEGRAM
Совсем скоро состоится релиз Android Gradle Plugin 9.0 (AGP), который полностью меняет подход к конфигурации Android‑проектов: удаляет устаревшие API, упрощает настройку и пересматривает организацию конфигурации.
Ключевые изменения:
👉 Переход на Gradle 9.X
👉 Поддержка Kotlin теперь встроена в AGP — подключение
org.jetbrains.kotlin.android больше не требуется и даже будет рушить сборку. Из плюсов — минус один плагин. 👉 Плагин
org.jetbrains.kotlin.multiplatform больше не будет работать с com.android.library и com.android.application. Используйте com.android.kotlin.multiplatform.library, а для приложения создавайте отдельный модуль. 👉 Массовые изменения в API — множество удалений без прямых альтернатив. В целом идёт отказ от старых публичных интерфейсов, ведь новые уже давно доступны, и авторы плагинов могут их использовать.
👉 Некоторые возможности конфигурации теперь будут доступны только в библиотечном плагине.
Чтобы корректно обновиться до новой версии, нужно, чтобы все плагины, подключённые в проект, поддержали необходимые изменения — или отказаться от них.
Подробнее обо всех изменениях — в документации
Надеюсь, Android Studio добавит ассистента по миграции. А вот авторам плагинов, похоже, прибавится работы 😅
Как вам перемены? Пойдут ли они на пользу скорости сборки и удобству использования AGP?
#Android #AndroidDev #Gradle #AGP #AndroidStudio
Please open Telegram to view this post
VIEW IN TELEGRAM
В Android Gradle Plugin (AGP) 9.0 и новее появился инструмент, которого ждали многие разработчики SDK и библиотек. Встречайте плагин Fused Library (
com.android.fused-library). Пока в экспериментальном режиме.Раньше, если вы разбивали свой код на много модулей, перед вами вставала дилемма: заставлять пользователя подключать 5 разных зависимостей или использовать неофициальные "fat-aar" скрипты. Теперь Google предлагает нативное решение.
Fused Library плагин позволяет взять несколько Android Library модулей и упаковать их в один AAR [1].
1️⃣ Для включения фичи надо будет добавить флаг в
gradle.properties:android.experimental.fusedLibrarySupport=true
2️⃣ Затем создаем модуль для публикации (например,
my-sdk-fused). В его build.gradle.kts добавляем:plugins {
id("com.android.fused-library")
`maven-publish`
}
androidFusedLibrary {
namespace = "dev.androidbroadcast.mysdk"
minSdk = 23
}
dependencies {
// Указываем модули для "слияния"
include(project(":core"))
include(project(":ui-components"))
// Можно вливать даже внешние либы!
include("dev.androidbroadcast:cool-fonts:1.0")
}Обратите внимание на
include — это ключевая команда для упаковки.3️⃣ Используем компонент
fusedLibraryComponent при публикации артефакта:publishing {
publications {
register<MavenPublication>("release") {
groupId = "dev.androidbroadcast"
artifactId = "fat-sdk"
version = "1.0.0"
from(components["fusedLibraryComponent"])
}
}
}Инструмент мощный, но есть особенности:
❌ Data Binding не поддерживается.
⚠️ Ресурсы: При совпадении имен побеждает ресурс из зависимости, указанной первой.
⚠️ Build Types: Нельзя слить debug и release в один проход, нужны разные fused-модули.
🐞 Source JAR: Пока есть известные проблемы с генерацией исходников.
Подробнее читайте в [документации](https://developer.android.com/build/publish-library/fused-library)
#Android #AndroidDev #Gradle #AGP #Maven
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯 Dagger Hilt блокирует переход на AGP 9.0
Android Gradle Plugin 9.0 официально зафиксировал новый стабильный конфигурационный API (вышла стабильная версия с релизом AS Otter FD 3) — это одно из самых значимых изменений в инфраструктуре Android и Kotlin Multiplatform за последние годы. Цели понятны и правильные лучше работа с кэшем и общая скорость сборок. Подробнее про все изменения я писал в отдельном посте
Google несколько релизов подряд аккуратно готовил экосистему к этому переходу, заранее добавив новый API и дав время авторам плагинов адаптироваться. Но на практике всё упирается в плагины.
Я столкнулся с тем, что Gradle-плагин Dagger Hilt до сих пор использует старую модель конфигурации и несовместим с новым DSL из AGP 9.0. В результате проект нельзя перевести на новую версию без отключения Hilt или включения режим совместимости. Иронично, что именно официальный инструмент от Google сейчас становится блокером для обновления.
Да, в AGP оставили compatibility-флаги, позволяющие продолжать сборку по старым правилам. Это спасает проекты от немедленного падения, но полностью отключает все ключевые преимущества AGP 9.0 — configuration cache, ускоренную конфигурацию и новую модель плагинов.
💬 Вы уже пробовали миграцию на AGP 9.0? Что блокирует? Делитесь в комментариях мнением.
UPD. По заявлениям подписчиков также есть проблемы в работе KAPT и KSP
#Android #AndroidDev #Gradle #Dagger #Hilt
UPD. 21 января вышел Dagger 2.59 с поддержкой AGP
Android Gradle Plugin 9.0 официально зафиксировал новый стабильный конфигурационный API (вышла стабильная версия с релизом AS Otter FD 3) — это одно из самых значимых изменений в инфраструктуре Android и Kotlin Multiplatform за последние годы. Цели понятны и правильные лучше работа с кэшем и общая скорость сборок. Подробнее про все изменения я писал в отдельном посте
Google несколько релизов подряд аккуратно готовил экосистему к этому переходу, заранее добавив новый API и дав время авторам плагинов адаптироваться. Но на практике всё упирается в плагины.
Я столкнулся с тем, что Gradle-плагин Dagger Hilt до сих пор использует старую модель конфигурации и несовместим с новым DSL из AGP 9.0. В результате проект нельзя перевести на новую версию без отключения Hilt или включения режим совместимости. Иронично, что именно официальный инструмент от Google сейчас становится блокером для обновления.
Да, в AGP оставили compatibility-флаги, позволяющие продолжать сборку по старым правилам. Это спасает проекты от немедленного падения, но полностью отключает все ключевые преимущества AGP 9.0 — configuration cache, ускоренную конфигурацию и новую модель плагинов.
UPD. По заявлениям подписчиков также есть проблемы в работе KAPT и KSP
#Android #AndroidDev #Gradle #Dagger #Hilt
Please open Telegram to view this post
VIEW IN TELEGRAM
Android Broadcast
🤯 Dagger Hilt блокирует переход на AGP 9.0 UPD. 21 января вышел Dagger 2.59 с поддержкой AGP Android Gradle Plugin 9.0 официально зафиксировал новый стабильный конфигурационный API (вышла стабильная версия с релизом AS Otter FD 3) — это одно из самых значимых…
🔥 В Dagger 2.59 добавили поддержку AGP 9.0. Одним блокером для миграции на AGP 9.0 стало меньше
#Android #Gradle
#Android #Gradle
Android Broadcast
🔥 В Dagger 2.59 добавили поддержку AGP 9.0. Одним блокером для миграции на AGP 9.0 стало меньше #Android #Gradle
Сразу после выхода Dagger с поддержкой AGP стал пробовать миграцию на AGP 9.0. Блокером послужил baselineprofile Gradle plugin. Текущая его стабильная версия 1.4.1 не поддерживает новый DSL, но зато альфа версия 1.5.0-alpha01 (вышла 17 декабря 2025) уже работает.
Учитывая, что это не влияет на код в рантайте, то я бы обновился в проде.
#Android #Gradle
Please open Telegram to view this post
VIEW IN TELEGRAM
Если у вас тяжёлая Android-сборка (много модулей, R8, CI с ограниченной памятью), имеет смысл принудительно завершать Kotlin Daemon после компиляции и до запуска R8 🔪
Kotlin Daemon нужен только на этапе компиляции Kotlin. После этого он спокойно живёт до конца сборки и держит память. R8 — один из самых прожорливых этапов по CPU и RAM 🔥 По итогу Daemon и R8 начинают конкурировать за ресурсы памяти
Что вы реально получаете если убивает Kotlin демона после компиляции кода:
🔗 Источник с измерениями и подробным разбором
#Android #Kotlin #R8 #Gradle
Please open Telegram to view this post
VIEW IN TELEGRAM
По умолчанию Android Gradle Plugin создаёт Gradle-задачи для запуска unit-тестов во всех доступных build types, что на практике почти никогда не нужно. Обычно тесты запускаются только для debug-сборки.
В реальных проектах (особенно с product flavors и большим количеством модулей) это приводит к сотням лишних задач, увеличению времени конфигурации и дополнительной нагрузке на IDE и CI.
Чтобы оптимизировать работу Gradle, начиная с AGP 9.0, можно в gradle.properties добавить:
android.onlyEnableUnitTestForTheTestedBuildType=true
После этого unit-тесты будут генерироваться только для основного тестируемого build type (как правило, debug). Это:
👉 убирает лишние Gradle-задачи;
👉 сокращает время конфигурации проекта;
👉 снижает потребление памяти;
👉 ускоряет локальную разработку и CI-пайплайны.
Если вы не запускаете unit-тесты для release-сборок (а так делают почти все), то включение этого флага — бесплатная оптимизация сборочной инфраструктуры.
Это хороший пример того, как дефолтные настройки инструментов ориентированы на универсальность, а не на эффективность, и почему их стоит регулярно пересматривать в контексте реальной архитектуры проекта.
#Android #AndroidDev #Gradle
Please open Telegram to view this post
VIEW IN TELEGRAM